/// <summary> /// 异步发送消息 /// </summary> /// <param name="listData">数据包</param> public void SendAsync(params byte[][] listData) { if (!TcpStateObject.IsConnected(client)) { throw new Exception("与服务端的连接已中断!"); } IList <ArraySegment <byte> > buffers = TcpStateObject.GetBuffers(this.OnlyData, DataLength, listData); client.Client.BeginSend(buffers, SocketFlags.None, SendCallBack, client); //if (this.OnlyData) //{ // byte[] Data = TcpStateObject.GetDataSend(listData, DataLength); // if (!TcpStateObject.IsConnected(client)) // { // throw new Exception("与服务端的连接已中断!"); // } // client.Client.BeginSend(Data, 0, Data.Length, SocketFlags.None, SendCallBack, client); //} //else //{ // if (!TcpStateObject.IsConnected(client)) // { // throw new Exception("与服务端的连接已中断!"); // } // client.Client.BeginSend(listData, 0, listData.Length, SocketFlags.None, SendCallBack, client); //} }
/** * 启动新线程,用于专门接收消息 */ private void StartReceive(string key, TcpClient client) { Task.Factory.StartNew(() => { Thread.CurrentThread.Name ??= "Tcp客户端-业务"; //用于控制异步接收消息 ManualResetEvent doReceive = new(false); //接收数据包 TcpStateObject obj = new(client, this.DataLength) { doReceive = doReceive }; while (!isClose) { if (TcpStateObject.IsConnected(client)) { Thread.Sleep(Millisecond); ReceiveAsync(obj); Thread.Sleep(Millisecond); } else { //如果发生异常,说明客户端失去连接,触发关闭事件 InsideClose(); OnComplete(obj.IpPort, EnSocketAction.Close); if (this.IsReconnect) { WhileReconnect(); } break; } } obj.Close(); }, TaskCreationOptions.LongRunning).ContinueWith((i) => i.Dispose()); //ThreadPool.QueueUserWorkItem(x => //{ // //接收数据包 // StateObject obj = new StateObject(client, this.DataLength) { doReceive = doReceive }; // while (!isClose) // { // if (StateObject.IsConnected(client)) // { // Thread.Sleep(Millisecond); // ReceiveAsync(obj); // Thread.Sleep(Millisecond); // } // else // { // //如果发生异常,说明客户端失去连接,触发关闭事件 // Close(); // OnComplete(obj.IpPort, EnSocketAction.Close); // break; // } // } // //client.Close(); //}); }
/** * 异步接收消息 */ private void ReceiveAsync(TcpStateObject obj) { obj.doReceive.Reset(); if (TcpStateObject.IsConnected(obj.Client)) { try { //obj.SocketClient.BeginReceive(obj.vs, SocketFlags.None, ReceiveCallBack, obj); obj.SocketClient.BeginReceive(obj.ListData, obj.WriteIndex, obj.ListData.Length - obj.WriteIndex, SocketFlags.None, ReceiveCallBack, obj); obj.doReceive.WaitOne(); } catch (Exception) { obj.Client.Close(); } } }
/// <summary> /// 重连,返回是否重连,如果没有断开是不会重连的 /// </summary> public bool Reconnection() { try { if (!isClose) { if (!TcpStateObject.IsConnected(client)) { string[] Connect = server.Split(':'); string ip = Connect[0]; int port = Connect[1].ToInt(); client.Close(); if (TcpBufferSize.Default == this.BufferSize) { client = new TcpClient(); } else { client = new TcpClient() { ReceiveBufferSize = (int)this.BufferSize, SendBufferSize = (int)this.BufferSize }; } client.Connect(ip, port); if (TcpStateObject.IsConnected(client)) { StartReceive(server, client); OnComplete(server, EnSocketAction.Connect); } else { InsideClose(); OnComplete(server, EnSocketAction.Fail); } } } return(true); } catch { InsideClose(); return(false); } }
/** * 连接的公共回调函数 */ private void ActionConnect(TcpClient client) { if (TcpStateObject.IsConnected(client)) { //OnComplete(client, EnSocketAction.Create); string key = server; //StateObject.GetIpPort(client); //client.NoDelay = true; StartReceive(key, client); OnComplete(key, EnSocketAction.Connect); } else { InsideClose(); OnComplete(server, EnSocketAction.Fail); if (this.IsReconnect) { WhileReconnect(); } } }
/** * 异步接收消息的回调函数 */ private void ReceiveCallBack(IAsyncResult ar) { TcpStateObject obj = ar.AsyncState as TcpStateObject; int count = -1; byte[] ListData = null; try { if (TcpStateObject.IsConnected(obj.Client)) { count = obj.SocketClient.EndReceive(ar); } if (count == 0) { obj.Client.Close(); } if (this.OnlyData) { if (obj.WriteIndex + count > 6) { Verify: byte[] headby = new byte[6]; Array.Copy(obj.ListData, 0, headby, 0, 6); int head = TcpStateObject.GetDataHead(headby); if (head != -1) { if (head + 6 > obj.ListData.Length) { obj.Client.Close(); obj.doReceive.Set(); return; } int writeIndex = (count + obj.WriteIndex) - (head + 6); if (writeIndex > -1) { ListData = new byte[head]; Array.Copy(obj.ListData, 6, ListData, 0, head); obj.WriteIndex = writeIndex; if (obj.WriteIndex > 0) { byte[] NewData = new byte[obj.WriteIndex]; Array.Copy(obj.ListData, head + 6, NewData, 0, obj.WriteIndex); Array.Clear(obj.ListData, 0, obj.WriteIndex + head + 6); Array.Copy(NewData, 0, obj.ListData, 0, obj.WriteIndex); } else { Array.Clear(obj.ListData, 0, head + 6); } //try //{ // ThreadPool.QueueUserWorkItem(x => // { // Received?.Invoke(obj.IpPort, x as byte[]);//触发接收事件 // }, ListData); //} //catch (Exception ex) //{ // Log.Error("多包线程池异常", ex, "Log/Tcp"); //} TcpStateObject.OnReceived(obj.IpPort, ListData, Received); if (obj.WriteIndex > 6) { count = 0; goto Verify; } } else { obj.WriteIndex = (count + obj.WriteIndex); obj.doReceive.Set(); return; } } else { obj.Client.Close(); } } } else { ListData = new byte[count]; Array.Copy(obj.ListData, 0, ListData, 0, count); Array.Clear(obj.ListData, 0, count); obj.WriteIndex = 0; //try //{ // ThreadPool.QueueUserWorkItem(x => // { // Received?.Invoke(obj.IpPort, x as byte[]);//触发接收事件 // }, ListData); //} //catch (Exception ex) //{ // Log.Error("多包线程池异常", ex, "Log/Tcp"); //} TcpStateObject.OnReceived(obj.IpPort, ListData, Received); } obj.doReceive.Set(); } catch (Exception) { obj.Client.Close(); obj.doReceive.Set(); return; } //if (count > 0) //{ // string msg = Encoding.UTF8.GetString(ListData, 0, count); // if (!string.IsNullOrEmpty(msg)) // { // Received?.Invoke(obj.IpPort, msg); // } //} }