/// <summary> /// 监听客户端连接的异步回调 /// </summary> /// <param name="ar"></param> private void Listen_Callback(IAsyncResult ar) { try { TcpListener listener = (TcpListener)ar.AsyncState; if (null != listener) { Socket ss = listener.EndAcceptSocket(ar); StateObject so = new StateObject(); so.socket = ss; so.point = ss.RemoteEndPoint as IPEndPoint; ss.BeginReceive(so.buffer, 0, StateObject.BUFFER_SIZE, SocketFlags.None, new AsyncCallback(Read_Callback), so); lock (_clients) { _clients.Add(so); } if (null != OnConnected) { var aud = new AsyncUserDataEvent(); aud.Data = _bufferPool.Get(); aud.Data.SetDataEvent(so, 0); OnConnected(this, aud); } HandleOnMessage(Environment.NewLine + Now + "Client [" + so.point.Address.ToString() + ":" + so.point.Port + "] connected."); _listener.BeginAcceptSocket(new AsyncCallback(Listen_Callback), _listener); } } catch (ObjectDisposedException e) { if (!IsStop) { HandleOnMessage(Now + "Listen_Callback error: " + e.Message + Environment.NewLine + e.StackTrace); } } }
/// <summary> /// 读取数据的回调 /// </summary> /// <param name="ar"></param> private void Read_Callback(IAsyncResult ar) { try { StateObject so = (StateObject)ar.AsyncState; lock (so) { if (null == so) { return; } Socket s = so.socket; int read = s.EndReceive(ar); if (read > 0) { if (null == so.Received) { so.Received = new byte[read]; so.length = read; } else { so.length += read; so.Received = Wbs.Utilities.CustomConvert.expand(so.Received, so.length); } Buffer.BlockCopy(so.buffer, 0, so.Received, so.length - read, read); s.BeginReceive(so.buffer, 0, StateObject.BUFFER_SIZE, SocketFlags.None, new AsyncCallback(Read_Callback), so); if (so.length >= so.Received[0]) { // 加入队列并等待处理 if (null != OnReceivedData) { var aud = new AsyncUserDataEvent(); aud.Data = _bufferPool.Get(); aud.Data.SetDataEvent(so, 2); OnReceivedData(this, aud); } so.ClearReceived(); } } else { HandleOnMessage(string.Format("{0}Iridium server {1}:{2} disconnected.", Now, so.point.Address.ToString(), so.point.Port)); if (null != OnDisconnected) { var aud = new AsyncUserDataEvent(); aud.Data = _bufferPool.Get(); aud.Data.SetDataEvent(so, 1); OnDisconnected(this, aud); } //so.socket.Shutdown(SocketShutdown.Both); //so.socket.Close(); } } } catch (Exception e) { HandleOnMessage(Now + "Read_Callback error: " + e.Message + Environment.NewLine + e.StackTrace); } }
/// <summary> /// 关闭一个连接。 /// </summary> /// <param name="e"></param> private void CloseClientSocket(SocketAsyncEventArgs e) { var aut = e.UserToken as AsyncUserToken; // socket 已经关闭过了,直接返回 if (null == aut.Socket) { return; } // 通知客户端断开事件 if (null != OnDisconnected) { var aude = new AsyncUserDataEvent(); aude.Data = _bufferPool.Get(); aude.Data.SetDataEvent(e, false); aude.Data.PackageType = AsyncDataPackageType.TCP; OnDisconnected(this, aude); } // 关闭 socket 关联的发送操作。 try { aut.Socket.Shutdown(SocketShutdown.Both); } // 屏蔽当 socket 已经关闭的异常。 catch (Exception) { } aut.Socket.Close(); aut.Socket = null; // 释放一个等待队列信号,以便让在连接 accept 队列中等待处理的新连接得到处理。 m_maxNumberAcceptedClients.Release(); // 将该连接节点的 SocketAsyncEventArgs 回收到 SocketAsyncEventArgsPool 池中等待继续使用。 saea_readWritePool.Push(e); // 从链接队列中移除节点 lock (_clients) { _clients.Remove(aut); } }
/// <summary> /// 客户端连接成功的处理过程。 /// 客户端的基本信息在此绑定到某一个 SocketAsyncEventArgs 中。 /// </summary> /// <param name="e"></param> private void ProcessAccept(SocketAsyncEventArgs e) { if (e.SocketError == SocketError.Success) { // 从 SocketAsyncEventArgsPool 池中取出一个空节点来保存新连接进来的客户端。 SocketAsyncEventArgs readEventArgs = saea_readWritePool.Pop(); // 将客户端信息附加到用户信息上。 var aut = readEventArgs.UserToken as AsyncUserToken; aut.Socket = e.AcceptSocket; aut.RecycleData(); // 将新入的链接加入队列 lock (_clients) { _clients.Add(aut); } // 通知处理客户端连接事件 if (null != OnConnected) { var aude = new AsyncUserDataEvent(); aude.Data = _bufferPool.Get(); aude.Data.SetDataEvent(readEventArgs, true); aude.Data.PackageType = AsyncDataPackageType.TCP; OnConnected(this, aude); } // 向新连接进来的客户端投递 receive 操作。 bool willRaiseEvent = e.AcceptSocket.ReceiveAsync(readEventArgs); // 如果客户端此时发送数据则需要立即处理。 if (!willRaiseEvent) { ProcessReceive(readEventArgs); } // 继续等待新的客户端连接。 StartAccept(e); } }
/// <summary> /// 接收客户端的数据或客户端的断开信息。 /// </summary> /// <param name="e"></param> private void ProcessReceive(SocketAsyncEventArgs e) { if (null == (e.UserToken as AsyncUserToken).Socket) { return; } // 如果 BytesTransferred 不为 0 且没有发送 SocketError,则说明收到客户端发送的信息。 if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success) { var token = e.UserToken as AsyncUserToken; lock (token) { token.ReceiveData(e.BytesTransferred, e.Buffer, e.Offset); if (token.Length >= token.Buffer[0]) { // 如果收到的是完整的包则直接发给前台处理 if (null != OnReceivedData) { var aude = new AsyncUserDataEvent(); aude.Data = _bufferPool.Get(); aude.Data.SetDataEvent(token); aude.Data.PackageType = AsyncDataPackageType.TCP; OnReceivedData(this, aude); // 消息接收完毕之后清空接收缓冲区 token.RecycleData(); } } } // 锁定socket? //lock (token.Socket) //{ // lock (_TCP_Buffer_Received)// 锁定缓冲区 // { // //var token = e.UserToken as AsyncUserToken; // var socket = token.SocketHandle; // // 如果缓冲区中有这个socket的数据,说明之前的数据收到的不完整,需要再组包 // if (_TCP_Buffer_Received.ContainsKey(socket)) // { // // 组包 // var data = _TCP_Buffer_Received[socket]; // data.ResizeData(e); // if (data.Buffer.Length >= data.Buffer[0]) // { // // 包长度足够之后从暂存缓存中移除节点 // _TCP_Buffer_Received.Remove(socket); // // 发送消息 // OnReceivedData(this, new AsyncUserDataEvent() { Data = data }); // } // } // else // { // if (e.BytesTransferred >= e.Buffer[e.Offset]) // { // // 如果收到的是完整的包则直接发给前台处理 // if (null != OnReceivedData) // { // var aude = new AsyncUserDataEvent(); // aude.Data = _bufferPool.Get(); // aude.Data.SetDataEvent(e, 0); // aude.Data.PackageType = AsyncDataPackageType.TCP; // OnReceivedData(this, aude); // } // } // else // { // //var aude = new AsyncUserDataEvent(); // var data = _bufferPool.Get(); // data.SetDataEvent(e, 0); // data.PackageType = AsyncDataPackageType.TCP; // _TCP_Buffer_Received.Add(socket, data); // } // } // } //} //回传收到的信息。 //e.SetBuffer(e.Offset, e.BytesTransferred); //e.SetBuffer(0, 0); // 数据接收完毕之后重新在连接上投递 receive 操作,如此循环,就可以不断的接收到客户端发送的数据。 bool willRaiseEvent = (e.UserToken as AsyncUserToken).Socket.ReceiveAsync(e);//token.Socket.SendAsync(e); if (!willRaiseEvent) { ProcessReceive(e); } } else { CloseClientSocket(e); } }
/// <summary> /// 处理UDP接受的线程 /// </summary> private void handleUdpReceive() { int len = 0; byte[] buffer = new byte[1024]; while (!stoped) { try { if (null != udpSocket) { len = 0; EndPoint clientEP = new IPEndPoint(IPAddress.Any, 0); len = udpSocket.ReceiveFrom(buffer, ref clientEP); lock (udpSocket) { var ip = (clientEP as IPEndPoint).Address.ToString(); var port = (clientEP as IPEndPoint).Port; var token = ip + ":" + port.ToString(); //AsyncUserToken token = new AsyncUserToken(); //token.IP = (clientEP as IPEndPoint).Address.ToString(); //token.Port = (clientEP as IPEndPoint).Port; lock (_UDP_Buffer_Received) { if (_UDP_Buffer_Received.ContainsKey(token)) { // 组包 var data = _UDP_Buffer_Received[token]; data.Buffer = CustomConvert.expand(data.Buffer, data.Buffer.Length + len); Buffer.BlockCopy(buffer, 0, data.Buffer, data.Buffer.Length - len, len); if (data.Buffer.Length >= data.Buffer[0]) { // 包长度足够之后从暂存缓存中移除节点 _UDP_Buffer_Received.Remove(token); // 发送消息 OnReceivedData(this, new AsyncUserDataEvent() { Data = data }); } } else { if (len >= buffer[0]) { // 如果收到的是完整的包则直接发给前台处理 if (null != OnReceivedData) { var aude = new AsyncUserDataEvent(); aude.Data = _bufferPool.Get(); aude.Data.SetDataEvent(ip, port, buffer, len); aude.Data.PackageType = AsyncDataPackageType.UDP; OnReceivedData(this, aude); } } else { //var aude = new AsyncUserDataEvent(); var data = _bufferPool.Get(); data.SetDataEvent(ip, port, buffer, len); data.PackageType = AsyncDataPackageType.UDP; _UDP_Buffer_Received.Add(token, data); } } } } } } catch (Exception e) { string a = e.Message; } } }