private void CloseClientSocket(string uid, bool isReceive = false) { if (string.IsNullOrEmpty(uid)) { return; } DuplexSocketAsyncEventArgsWithId _saea = m_readWritePool.FindByUID(uid); if (_saea != null) { m_bufferManager.FreeBuffer(_saea.ReceiveSAEA); Socket _socket = (_saea.ReceiveSAEA.UserToken as AsyncUserToken).Socket; try { _socket.Shutdown(SocketShutdown.Both); _socket = null; } catch { LogOutEvent(null, MessageType.Error, "客户端已经关闭"); //OnSended(uid, "客户端已经关闭"); } this.m_semaphoreAcceptedClients.Release(); Interlocked.Decrement(ref this.m_numConnections); this.m_readWritePool.Push(_saea); if (this.m_readWritePool.Count == 1) { StartAccept(null); } } }
/// <summary> /// 把一个使用完的连接放回连接池。 /// </summary> /// <param name="item"></param> internal void Push(DuplexSocketAsyncEventArgsWithId item) { if (item == null) { throw new ArgumentNullException("DuplexSocketAsyncEventArgsWithId 对象为空"); } if (item.State == true) { if (m_busypool.Keys.Count != 0) { if (m_busypool.Keys.Contains(item.UID)) { m_busypool.Remove(item.UID); } else { throw new ArgumentException("SocketAsyncEventWithId不在忙碌队列中"); } } else { throw new ArgumentException("忙碌队列为空"); } } item.UID = "-1"; item.State = false; lock (this.m_pool) { this.m_pool.Push(item); } }
/// <summary> /// send message /// </summary> /// <param name="uid"></param> /// <param name="msg"></param> public void Send(string uid, string msg) { if (string.IsNullOrEmpty(uid) || string.IsNullOrEmpty(msg)) { return; } DuplexSocketAsyncEventArgsWithId _socket = m_readWritePool.FindByUID(uid); //说明用户已经断开 //100 发送成功 //200 发送失败 //300 用户不在线 //其它 表示异常的信息 if (_socket == null) { OnSended(uid, MessageType.UseOffline.ToString()); } else { string _msgTmpl = @"[length={0}]{1}"; MySocketAsyncEventArgs _e = _socket.SendSAEA; if (_e.SocketError == SocketError.Success) { int _i = 0; try { string _msg = string.Format(_msgTmpl, msg.Length, msg); byte[] _sendBuffer = Encoding.Unicode.GetBytes(_msg); _e.SetBuffer(_sendBuffer, 0, _sendBuffer.Length); bool _willRaiseEvent = (_e.UserToken as Socket).SendAsync(_e); if (!_willRaiseEvent) { this.ProcessSend(_e); } } catch (Exception ee) { if (_i <= 5) { _i++; //如果发送出现异常就延迟0.01秒再发 Thread.Sleep(10); Send(uid, msg); } else { OnSended(uid, ee.ToString()); } } } else { OnSended(uid, MessageType.Failed.ToString()); this.CloseClientSocket(_e.UID, false); } } }
private void ProcessAccept(SocketAsyncEventArgs accepter) { if (accepter.LastOperation != SocketAsyncOperation.Accept) { return; } //if (accepter.BytesTransferred <= 0) //检查发送的长度是否大于0,不是就返回 // return; string _uid = GetUid(accepter); try { if (string.IsNullOrEmpty(_uid)) { return; } if (m_readWritePool.BusyPoolContains(_uid)) { LogOutEvent(null, SocketMessageType.Error, string.Format("The Socket Not Connect {0}", accepter.AcceptSocket.RemoteEndPoint)); this.CloseClientSocket(_uid, false); return; } DuplexSocketAsyncEventArgsWithId _reader = this.m_readWritePool.Pop(_uid); _reader.ReceiveSAEA.UserToken = new AsyncUserToken(accepter.AcceptSocket); _reader.SendSAEA.UserToken = new AsyncUserToken(accepter.AcceptSocket); if (AcceptUser != null) { AcceptUser(_uid, (accepter.AcceptSocket.RemoteEndPoint as IPEndPoint).Address.ToString()); } //if (m_bufferManager.SetBuffer(_reader.ReceiveSAEA)) if (!(_reader.ReceiveSAEA.UserToken as AsyncUserToken).Socket.ReceiveAsync(_reader.ReceiveSAEA)) { ProcessReceive(_reader.ReceiveSAEA); } } catch (Exception ee) { LogOutEvent(null, SocketMessageType.Error, ee.Message); } finally { Interlocked.Increment(ref this.m_numConnections); this.StartAccept(accepter); } }
/// <summary> /// 查找在线用户连接,返回这个连接。 /// </summary> /// <param name="uid"></param> /// <returns></returns> internal DuplexSocketAsyncEventArgsWithId FindByUID(string uid) { if (string.IsNullOrEmpty(uid)) { return(null); } string _key = OnlineUID.FirstOrDefault(si => { return(si == uid); }); if (string.IsNullOrEmpty(_key)) { throw new ArgumentException("未发现用户链接 " + uid); } DuplexSocketAsyncEventArgsWithId _si = m_busypool[_key]; return(_si); }
/// <summary> /// 用于获取一个可用连接给用户。 /// </summary> /// <param name="uid"></param> /// <returns></returns> internal DuplexSocketAsyncEventArgsWithId Pop(string uid) { if (string.IsNullOrEmpty(uid)) { return(null); } DuplexSocketAsyncEventArgsWithId _si = null; lock (this.m_pool) { _si = this.m_pool.Pop(); } _si.UID = uid; _si.State = true; m_busypool.Add(uid, _si); return(_si); }
/// <summary> /// 连接服务端 /// </summary> public bool Connect() { MySocketAsyncEventArgs connectArgs = new MySocketAsyncEventArgs("Connect"); connectArgs.UserToken = new AsyncUserToken(clientSocket); connectArgs.RemoteEndPoint = this.hostEndPoint; connectArgs.Completed += new EventHandler <SocketAsyncEventArgs>(OnConnect); clientSocket.ConnectAsync(connectArgs); //等待连接结果 autoConnectEvent.WaitOne(); SocketError errorCode = connectArgs.SocketError; if (errorCode == SocketError.Success) { this.m_bufferManager.InitBuffer(); _readWirted = new DuplexSocketAsyncEventArgsWithId(); //_readWirted.State = true; _readWirted.ReceiveSAEA.Completed += OnReceive; _readWirted.SendSAEA.Completed += OnSend; _readWirted.ReceiveSAEA.UserToken = new AsyncUserToken(clientSocket); _readWirted.SendSAEA.UserToken = new AsyncUserToken(clientSocket); this.m_bufferManager.SetBuffer(_readWirted.ReceiveSAEA); if (!(_readWirted.ReceiveSAEA.UserToken as AsyncUserToken).Socket.ReceiveAsync(_readWirted.ReceiveSAEA)) { ProcessReceive(_readWirted.ReceiveSAEA); } if (StartListenThread != null) { StartListenThread(); } return(true); } else { //throw new SocketException((Int32)errorCode); return(false); } }
public void Init() { this.m_bufferManager.InitBuffer(); DuplexSocketAsyncEventArgsWithId _readWirted; for (int i = 0; i < this.m_numConcurrence; i++) { _readWirted = new DuplexSocketAsyncEventArgsWithId(); //_readWirted.State = true; _readWirted.ReceiveSAEA.Completed += OnCompleted; _readWirted.SendSAEA.Completed += OnCompleted; _readWirted.ReceiveSAEA.UserToken = new AsyncUserToken(null); _readWirted.SendSAEA.UserToken = new AsyncUserToken(null); //只给接收的SocketAsyncEventArgs设置缓冲区 this.m_bufferManager.SetBuffer(_readWirted.ReceiveSAEA); this.m_readWritePool.Push(_readWirted); } m_serverState = ServerState.Inited; }