private void CloseClientSocket(string uid, bool isReceive = false) { if (string.IsNullOrEmpty(uid)) { return; } SocketAsyncEventArgsWithIdDuplex _saea = m_readWritePool.FindByUID(uid); if (_saea != null) { m_bufferManager.FreeBuffer(_saea.ReceiveSAEA); Socket _socket = (_saea.ReceiveSAEA.UserToken as Socket); try { _socket.Shutdown(SocketShutdown.Both); _socket = null; } catch { LogOutEvent(null, SocketMessageType.Error, "客户端已经关闭"); } 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(SocketAsyncEventArgsWithIdDuplex 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> /// 连接服务端 /// </summary> public bool Connect() { SocketAsyncEventArgsImpl connectArgs = new SocketAsyncEventArgsImpl(SocketAsyncType.Connect); connectArgs.UserToken = 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 SocketAsyncEventArgsWithIdDuplex(); _readWirted.ReceiveSAEA.Completed += OnReceive; _readWirted.SendSAEA.Completed += OnSend; _readWirted.ReceiveSAEA.UserToken = clientSocket; _readWirted.SendSAEA.UserToken = clientSocket; this.m_bufferManager.SetBuffer(_readWirted.ReceiveSAEA); ListenAsync(); return(true); } else { return(false); } }
public void Init() { this.m_bufferManager.InitBuffer(); SocketAsyncEventArgsWithIdDuplex _readWirted; for (int i = 0; i < this.m_numConcurrence; i++) { _readWirted = new SocketAsyncEventArgsWithIdDuplex(); _readWirted.ReceiveSAEA.Completed += OnCompleted; _readWirted.SendSAEA.Completed += OnCompleted; this.m_bufferManager.SetBuffer(_readWirted.ReceiveSAEA); this.m_readWritePool.Push(_readWirted); } m_serverState = SocketServerState.Inited; }
/// <summary> /// 查找在线用户连接,返回这个连接。 /// </summary> /// <param name="uid"></param> /// <returns></returns> internal SocketAsyncEventArgsWithIdDuplex 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); } SocketAsyncEventArgsWithIdDuplex _si = m_busypool[_key]; return(_si); }
/// <summary> /// 用于获取一个可用连接给用户。 /// </summary> /// <param name="uid"></param> /// <returns></returns> internal SocketAsyncEventArgsWithIdDuplex Pop(string uid) { if (string.IsNullOrEmpty(uid)) { return(null); } SocketAsyncEventArgsWithIdDuplex _si = null; lock (this.m_pool) { _si = this.m_pool.Pop(); } _si.UID = uid; _si.State = true; m_busypool.Add(uid, _si); return(_si); }
private void ProcessAccept(SocketAsyncEventArgs accepter) { if (accepter.LastOperation != SocketAsyncOperation.Accept) { return; } try { if (accepter.SocketError == SocketError.Success) { string _uid = GetUid(accepter); if (m_readWritePool.BusyPoolContains(_uid)) { LogOutEvent(null, SocketMessageType.Error, string.Format("The client[{0}] is alreadly in connnect", accepter.AcceptSocket.RemoteEndPoint)); this.CloseClientSocket(_uid, false); return; } SocketAsyncEventArgsWithIdDuplex _reader = this.m_readWritePool.Pop(_uid); _reader.ReceiveSAEA.UserToken = accepter.AcceptSocket; _reader.SendSAEA.UserToken = accepter.AcceptSocket; if (AcceptUser != null) { AcceptUser(_uid, (accepter.AcceptSocket.RemoteEndPoint as IPEndPoint).Address.ToString()); } if (!(_reader.ReceiveSAEA.UserToken as Socket).ReceiveAsync(_reader.ReceiveSAEA)) { ProcessReceive(_reader.ReceiveSAEA); } } } finally { Interlocked.Increment(ref this.m_numConnections); this.StartAccept(accepter); } }
/// <summary> /// /// </summary> /// <param name="uid"></param> /// <param name="msg"></param> /// <param name="type"></param> public void SendMessageAsync(string uid, string msg, bool allUser = false, SocketMessageInfoType type = SocketMessageInfoType.NONE) { if ((!allUser && string.IsNullOrEmpty(uid)) || string.IsNullOrEmpty(msg)) { return; } if (allUser) { if (this.m_readWritePool.m_busypool.Count == 0) { LogOutEvent(null, SocketMessageType.Error, string.Format("No client online")); } foreach (string id in this.m_readWritePool.m_busypool.Keys) { SendMessageAsync(id, msg, false, type); } } else { SocketAsyncEventArgsWithIdDuplex _socket = m_readWritePool.FindByUID(uid); if (_socket == null) { OnSended(uid, SocketMessageType.UseOffline.ToString()); } else { string _msgTmpl = @"[length={0}][MSG={1}]{2}"; SocketAsyncEventArgsImpl _e = _socket.SendSAEA; if (_e.SocketError == SocketError.Success) { int _i = 0; try { string _msg = string.Format(_msgTmpl, msg.Length, type.ToString(), 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++; Thread.Sleep(10); SendMessageAsync(uid, msg, allUser, type); } else { OnSended(uid, ee.ToString()); } } } else { OnSended(uid, SocketMessageType.Failed.ToString()); this.CloseClientSocket(_e.UID, false); } } } }