C# 的TCP Socket (异步方式)
C# TCP socket发送大数据包时,接收端和发送端数据不一致 服务端接收Receive不完全
服务器端:
public static ManualResetEvent allDone = new ManualResetEvent(false); IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), port); Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); listener.Bind(localEndPoint); listener.Listen(30); while (true) { allDone.Reset(); listener.BeginAccept(new AsyncCallback(AcceptCallback), listener); allDone.WaitOne(); }
public static void AcceptCallback(IAsyncResult ar) { try { if (IsListening) { allDone.Set(); Socket listener = (Socket)ar.AsyncState; Socket handler = listener.EndAccept(ar); StateObject state = new StateObject(); state.workSocket = handler; handler.BeginReceive(state.headbuffer, 0, StateObject.HeadBufferSize, 0, new AsyncCallback(ReceiveHead), state); } } catch (System.Exception ex) { log.ErrorFormat("AcceptCallback异常,原因:{0}", ex.Message); } } private static void ReceiveHead(IAsyncResult ar) { try { StateObject state = (StateObject)ar.AsyncState; Socket handler = state.workSocket; int bytesRead = handler.EndReceive(ar); uint length = ByteTouint(state.headbuffer, 3, 4); state.length = (int)length - state.headbuffer.Length; state.bodybuffer = new byte[length - state.headbuffer.Length]; handler.BeginReceive(state.bodybuffer, 0, state.bodybuffer.Length, 0, new AsyncCallback(ReadCallback), state); } catch (System.Exception ex) { log.ErrorFormat("ReceiveHead异常,原因:{0}", ex.Message + ex.StackTrace); } }
public static void ReadCallback(IAsyncResult ar) { StateObject state = (StateObject)ar.AsyncState; Socket handler = state.workSocket; int bytesRead = handler.EndReceive(ar); //接收的字节在state.bodybuffer里,下面开始处理 }
已知接收长度的话可以把ReceiveHead函数去掉,直接进入ReadCallback里。
加入ReceiveHead是因为协议一般在开头几个固定的字节里有后面数据包的长度,所以先接收头,再根据解析出的数据包长度接收后面的。
StateObject定义如下,可以不要headbuffer HeadBufferSize
public class StateObject { public Socket workSocket = null; public const int HeadBufferSize = 7; public byte[] headbuffer = new byte[HeadBufferSize]; public byte[] bodybuffer; public int length; }
客户端发送数据 C# 的TCP Socket (同步方式)