由于TCP在发送时,会将若干条消息合并到一起发送,所以会导致一条信息中有多条内容。
这次的做法和之前的自己的demo相同, 也是转为4字节的int,放到每条要发送信息的首部,逐步进行解析
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace TcpServer { class Message { private byte[] data = new byte[1024]; private int startIndex = 0; public byte[] Data { get { return data; } } public int StartIndex { get { return startIndex; } } public int RemainSize { get { return data.Length - startIndex; } } public void AddCount(int count) { startIndex += count; } /// <summary> /// 解析数据 /// </summary> public void ReadMessage() { while (true) { if (startIndex <= 4) { return; } int count = BitConverter.ToInt32(data, 0); if ((startIndex - 4) >= count) { string s = System.Text.Encoding.UTF8.GetString(data, 4, count); Array.Copy(data, count + 4, data, 0, startIndex - 4 - count); startIndex -= count + 4; Console.WriteLine(count +" "+s); } else break; } } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net.Sockets; using System.Net; namespace TcpServer { class Program { static byte[] dataBuffer = new byte[1024]; static void Main(string[] args) { StartServerAsync(); Console.ReadKey(); } static void StartServerAsync() { Socket socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPAddress iPAddress = IPAddress.Parse("192.168.200.1"); IPEndPoint iPEndPoint = new IPEndPoint(iPAddress, 88); socketServer.Bind(iPEndPoint); socketServer.Listen(10); //Socket clientSocket = socketServer.Accept(); 下面支持多个客户端,改为异步, 之前c++服务器用的epoll这里似乎不需要关注 socketServer.BeginAccept(AcceptCallBack, socketServer); } static Message msg=new Message(); static void AcceptCallBack(IAsyncResult ar) { Socket socketServer = ar.AsyncState as Socket; Socket socketClient = socketServer.EndAccept(ar); string msgStr = "Hello"; socketClient.Send(System.Text.Encoding.UTF8.GetBytes(msgStr)); socketClient.BeginReceive(msg.Data, msg.StartIndex, msg.RemainSize, SocketFlags.None, ReceiveCallBack, socketClient); socketServer.BeginAccept(AcceptCallBack, socketServer); } static void ReceiveCallBack(IAsyncResult ar) { // ar.AsyncState 可以获得之前传递的object Socket socketClient=null ; try { socketClient = ar.AsyncState as Socket; int count = socketClient.EndReceive(ar); if (count == 0) { //即便是空数据也不会是0,客户端不会发送空数据, 只有在结束时才有0的可能性 socketClient.Close(); return; } msg.AddCount(count); msg.ReadMessage(); socketClient.BeginReceive(msg.Data, msg.StartIndex, msg.RemainSize, SocketFlags.None, ReceiveCallBack, socketClient); } catch (Exception e) { Console.WriteLine(e); if (socketClient != null) { socketClient.Close(); } } } void StartServerSync() { Socket socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPAddress iPAddress = IPAddress.Parse("192.168.200.1"); IPEndPoint iPEndPoint = new IPEndPoint(iPAddress, 88); socketServer.Bind(iPEndPoint); socketServer.Listen(10); Socket clientSocket = socketServer.Accept(); string msg = "Hello"; clientSocket.Send(System.Text.Encoding.UTF8.GetBytes(msg)); byte[] databuffer = new byte[1024]; int count = clientSocket.Receive(databuffer); string megReceive = System.Text.Encoding.UTF8.GetString(databuffer, 0, count); Console.Write(databuffer); clientSocket.Close(); socketServer.Close(); } } }