写一个c#socket通讯服务器,用同步接收报文数据,并解决粘包示例
时间: 2024-02-03 18:12:55 浏览: 130
以下是一个简单的 C# Socket 服务器,使用同步接收报文数据,并解决粘包问题:
```csharp
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class Server
{
static void Main(string[] args)
{
// 创建一个 TCP/IP socket
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// 绑定本地 IP 地址和端口号
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8080);
listener.Bind(localEndPoint);
// 开始监听客户端连接
listener.Listen(100);
Console.WriteLine("等待客户端连接...");
Socket handler = listener.Accept();
// 循环接收客户端报文数据
byte[] buffer = new byte[1024];
int offset = 0;
int count = 0;
while (true)
{
try
{
// 接收客户端报文数据
count = handler.Receive(buffer, offset, buffer.Length - offset, SocketFlags.None);
// 如果接收到的数据长度为 0,说明客户端关闭了连接
if (count == 0)
{
Console.WriteLine("客户端已经关闭了连接。");
break;
}
offset += count;
// 解决粘包问题
while (true)
{
// 判断是否已经接收到完整的报文数据
int messageLength = GetMessageLength(buffer);
if (messageLength == -1 || offset < messageLength)
{
// 如果接收到的数据长度不足一个完整的报文数据,继续接收
break;
}
// 解析报文数据
string message = Encoding.UTF8.GetString(buffer, 0, messageLength);
Console.WriteLine("接收到客户端的报文数据:" + message);
// 处理报文数据
byte[] response = Encoding.UTF8.GetBytes("已经接收到您的消息:" + message);
handler.Send(response);
// 移动缓冲区,准备接收下一个报文数据
offset -= messageLength;
Array.Copy(buffer, messageLength, buffer, 0, offset);
}
}
catch (SocketException ex)
{
Console.WriteLine("发生了 Socket 异常:" + ex.Message);
break;
}
catch (Exception ex)
{
Console.WriteLine("发生了异常:" + ex.Message);
break;
}
}
// 关闭 socket 连接
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
static int GetMessageLength(byte[] buffer)
{
if (buffer.Length < 4)
{
return -1;
}
int length = BitConverter.ToInt32(buffer, 0);
if (length <= 0 || length > buffer.Length)
{
return -1;
}
return length;
}
}
```
在本例中,我们使用了一个 `GetMessageLength` 函数来获取报文数据的长度。这个函数的实现方式是在报文数据的前 4 个字节中存储报文数据的长度,因此只需要读取这 4 个字节即可。如果读取到的长度小于等于 0 或大于缓冲区的长度,说明读取到的数据不是一个完整的报文数据,需要继续接收。如果读取到的长度等于缓冲区的长度,说明可能出现了粘包问题,需要继续接收。只有当读取到的长度等于报文数据的长度时,我们才能解析出完整的报文数据,进行处理。
阅读全文