/// <summary> /// Use underline socket to send protocol message async. /// </summary> /// <param name="vMessage">The protocol message to be sended.</param> public void SendMessage(System.Object vMsg) { Log.Info("一个消息需要发送"); if (State != ConnectionState.Established) { Log.Info("一个消息需要发送 1"); Debug.WriteLine(String.Format("SendMessage Error:in State {0}", State)); return; } if (vMsg == null) { Log.Info("一个消息需要发送 2"); Debug.WriteLine(String.Format("SendMessage Error:vMsg is null")); return; } ArraySegment <Byte> sndBuf = ProtoHelper.EncodeMessage(vMsg, vMsg is IResponse); SocketAsyncEventArgs sendEventArgs = new SocketAsyncEventArgs(); sendEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(OnCompletedForSend); sendEventArgs.SetBuffer(sndBuf.Array, sndBuf.Offset, sndBuf.Count); Debug.WriteLine(string.Format("SendMessage Send {0}", vMsg.GetType().Name)); Log.Info(string.Format("SendMessage Send {0}", vMsg.GetType().Name)); if (!ConnSocket.SendAsync(sendEventArgs)) { OnCompletedForSendImpl(sendEventArgs); sendEventArgs.Dispose(); } }
///// <summary> ///// shutdown the socket ///// </summary> //public void Shutdown() //{ // try // { // lock (_lockSocket) // { // ////Console.WriteLine("Shutdown::lock (_lockPeer)"); // ConnSocket.Shutdown(SocketShutdown.Both); // } // } // catch (Exception) // { // //String msg = String.Format("{0}:{1}", ex.GetType().ToString(), ex.Message); // //Debug.WriteLine(msg); // //Console.WriteLine(msg); // //throw ex; // } // //Console.WriteLine("Client SHUTDOWN!"); //} /// <summary> /// 断开soket /// </summary> private void SocketDisconnect() { try { if (ConnSocket != null) { lock (_lockSocket) { // 启动断开连接的timer if (m_disconnectTimer == null) { m_disconnectTimer = new Timer((c) => { if (ConnSocket.Connected) { return; } if (State != ConnectionState.Disconnecting) { return; } // 记录日志 Debug.WriteLine(string.Format("SocketDisconnect Disconnected timer start...")); FireEventOnLogPrint("Disconnect.Timer" + "state=" + State); // 设置状态 State = ConnectionState.Closed; // 发送连接断开的消息 var vMsg = new CCMSGConnectionBreak(); RecvQueue.Enqueue(new KeyValuePair <int, object>(vMsg.MessageId, vMsg)); // 清理timer if (m_disconnectTimer != null) { m_disconnectTimer.Dispose(); m_disconnectTimer = null; } }, null, 500, 1000); // 500毫秒后启动, 1000毫秒检查一次 } ConnSocket.Shutdown(SocketShutdown.Both); //ConnSocket.Disconnect(false); } } } catch (Exception ex) { String msg = String.Format("{0}:{1}", ex.GetType().ToString(), ex.Message); Debug.WriteLine(msg); //throw ex; } }
public void OnDisconnect() { if (!_isConnected) { return; } _isConnected = false; ConnSocket.Close(); if (null != OnDisconnectListener) { OnDisconnectListener(this); } }
public void Send(byte[] bytes, int length, int offset = 0) { if (!IsConnected) { return; } MemoryStream sendBuffer = ObjectAllocatorHolder <MemoryStream> .Allocate(); sendBuffer.Seek(0, SeekOrigin.Begin); sendBuffer.SetLength(0); //var lenArray = BitConverter.GetBytes(length); if (!_littleEndian) { sendBuffer.WriteByte((byte)(length >> 24)); sendBuffer.WriteByte((byte)(length >> 16)); sendBuffer.WriteByte((byte)(length >> 8)); sendBuffer.WriteByte((byte)length); } else { sendBuffer.WriteByte((byte)length); sendBuffer.WriteByte((byte)(length >> 8)); sendBuffer.WriteByte((byte)(length >> 16)); sendBuffer.WriteByte((byte)(length >> 24)); } sendBuffer.Write(bytes, offset, length); //Logger.Debug("RealSendMsg"); try { var async = ConnSocket.Send(sendBuffer.GetBuffer(), 0, (int)sendBuffer.Length, SocketFlags.None); } catch (Exception e) { Logger.ErrorFormat("tcp send failed error {0} {1}", e, _connectid); OnDisconnect(); } finally { ObjectAllocatorHolder <MemoryStream> .Free(sendBuffer); } }
public void Send(byte[] bytes, int length, int offset = 0) { if (!IsConnected) { return; } SendSocketAsyncEventArgsExt sendArg = ObjectAllocatorHolder <SendSocketAsyncEventArgsExt> .Allocate(); sendArg.Completed += OnSendComplete; var sendMs = sendArg.SendBuffer; sendMs.Position = 0; sendMs.SetLength(0); var lenArray = BitConverter.GetBytes(length); if (!_littleEndian) { sendMs.WriteByte(lenArray[3]); sendMs.WriteByte(lenArray[2]); sendMs.WriteByte(lenArray[1]); sendMs.WriteByte(lenArray[0]); } else { sendMs.WriteByte(lenArray[0]); sendMs.WriteByte(lenArray[1]); sendMs.WriteByte(lenArray[2]); sendMs.WriteByte(lenArray[3]); } sendMs.Write(bytes, offset, length); sendArg.SetBuffer(sendMs.GetBuffer(), 0, (int)sendMs.Length); //Logger.Debug("RealSendMsg"); var async = ConnSocket.SendAsync(sendArg); if (!async) { OnSend(sendArg); } }
public void StartReceive(SocketAsyncEventArgs receiveArg) { if (null == ConnSocket) { return; } if (null == receiveArg) { receiveArg = ObjectAllocatorHolder <ReceiveSocketAsyncEventArgsExt> .Allocate(); receiveArg.Completed += OnReceiveComplete; } var async = ConnSocket.ReceiveAsync(receiveArg); if (!async) { OnReceive(receiveArg); } }
private void OnCompletedForConnectImpl(SocketAsyncEventArgs e) { try { if (e.SocketError == SocketError.Success) { /// Change connection state to ready State = ConnectionState.Established; // as soon as the client is connected, post a receive to the connection if (!ConnSocket.ReceiveAsync(m_receiveEventArg)) { OnCompletedForReceiveImpl(m_receiveEventArg); } /// Make a connection ready notification CCMSGConnectionReady ccReadyMsg = new CCMSGConnectionReady(); RecvQueue.Enqueue(new KeyValuePair <int, object>(ccReadyMsg.MessageId, ccReadyMsg)); return; } else { goto FAIL_CONNECT; } } catch { goto FAIL_CONNECT; } FAIL_CONNECT: CCMSGConnectionFailure ccFailMsg = new CCMSGConnectionFailure(); lock (RecvQueue) { RecvQueue.Enqueue(new KeyValuePair <int, object>(ccFailMsg.MessageId, ccFailMsg)); } State = ConnectionState.Closed; }
/// <summary> /// 清理关闭soket /// Close all work and release all resource. /// </summary> private void SocketClose() { try { if (ConnSocket != null) { lock (_lockSocket) { ConnSocket.Close(); } } // 删除两个IDispose数据,避免connect释放不了的问题 if (m_connEventArg != null) { m_connEventArg.Dispose(); m_connEventArg = null; } if (m_receiveEventArg != null) { m_receiveEventArg.Dispose(); m_receiveEventArg = null; } // 清理timer if (m_disconnectTimer != null) { m_disconnectTimer.Dispose(); m_disconnectTimer = null; } } catch (Exception ex) { String msg = String.Format("{0}:{1}", ex.GetType().ToString(), ex.Message); Debug.WriteLine(msg); //throw ex; } }
private void OnCompletedForReceiveImpl(SocketAsyncEventArgs e) { //Log.Info("接收到消息 Count = "+ e.BytesTransferred); // Log.Info("sadsadsadsa " + e.BytesTransferred); try { //Log.Info($"SocketError :{ e.SocketError}"); if (e.SocketError == SocketError.Success && e.BytesTransferred != 0) { // Log.Info("开始处理消息"); // at first, write state.buffer to recvcache RecvCache.Write(e.Buffer, e.BytesTransferred); //Debug.WriteLine(string.Format("OnCompletedForReceiveImpl Receive {0} RecvCache.Length={1}", e.BytesTransferred, RecvCache.Length)); // second, push the msg to recvqueue and decode message while (true) { ushort msgId = 0; bool flag; object msg = ProtoHelper.DecodeMessage(RecvCache, out msgId, out flag); //Log.Msg(msg.GetType()); if (msg == null) { break; } lock (RecvQueue) { var eMsg = new CCMSGConnectionRevMsg(); eMsg.MessageInfo.Message = msg as IMessage; eMsg.MessageInfo.Opcode = (ushort)msgId; eMsg.MessageInfo.flag = flag; // Log.Info("接收到消息 并且丢进了队列"); RecvQueue.Enqueue(new KeyValuePair <int, object>(eMsg.MessageId, eMsg)); } // all cache is handled if (RecvCache.Length == 0) { break; } } //Debug.WriteLine(string.Format("OnCompletedForReceiveImpl Receive End, RecvCache.Length={0}", RecvCache.Length)); RecvCache.Crunch(); // third, restart the async receive process m_receiveEventArg.SetBuffer(0, ProtoConst.MAX_PACKAGE_LENGTH); if (!ConnSocket.ReceiveAsync(m_receiveEventArg)) { OnCompletedForReceiveImpl(m_receiveEventArg); } return; } else { throw new Exception(string.Format("The result of ReceiveAsync is not correct, SocketError={0} BytesTransferred={1}", e.SocketError, e.BytesTransferred)); } } catch (Exception ex) { // Client exception means connection is disconnected // Or, there is an bad message format in byte stream CCMSGConnectionRecvFailure eMsg = new CCMSGConnectionRecvFailure(); eMsg.ExceptionInfo = ex.ToString(); lock (RecvQueue) { RecvQueue.Enqueue(new KeyValuePair <int, object>(eMsg.MessageId, eMsg)); } goto BREAK_CONNECT; } BREAK_CONNECT: // when receive action is over, which represents that socket can't receive any data lock (RecvQueue) { if (State == ConnectionState.Established || State == ConnectionState.Disconnecting) // 这个状态是为了让客户端主动断开服务器的时候 { State = ConnectionState.Closed; var vMsg = new CCMSGConnectionBreak(); RecvQueue.Enqueue(new KeyValuePair <int, object>(vMsg.MessageId, vMsg)); } } }
private void OnCompletedForReceiveImpl(SocketAsyncEventArgs e) { try { if (e.SocketError == SocketError.Success && e.BytesTransferred != 0) { // at first, write state.buffer to recvcache RecvCache.Write(e.Buffer, e.BytesTransferred); //Debug.WriteLine(string.Format("OnCompletedForReceiveImpl Receive {0} RecvCache.Length={1}", e.BytesTransferred, RecvCache.Length)); // second, push the msg to recvqueue and decode message while (true) { var msgId = 0; object msg = ProtoHelper.DecodeMessage(RecvCache, Provider, out msgId); if (msg == null) { break; } lock (RecvQueue) { RecvQueue.Enqueue(new KeyValuePair <int, object>(msgId, msg)); } // all cache is handled if (RecvCache.Length == 0) { break; } } //Debug.WriteLine(string.Format("OnCompletedForReceiveImpl Receive End, RecvCache.Length={0}", RecvCache.Length)); RecvCache.Crunch(); // third, restart the async receive process m_receiveEventArg.SetBuffer(0, ProtoConst.MAX_PACKAGE_LENGTH); if (!ConnSocket.ReceiveAsync(m_receiveEventArg)) { OnCompletedForReceiveImpl(m_receiveEventArg); } return; } else { throw new Exception(string.Format("The result of ReceiveAsync is not correct, SocketError={0} BytesTransferred={1}", e.SocketError, e.BytesTransferred)); } } catch (Exception ex) { // Connection exception means connection is disconnected // Or, there is an bad message format in byte stream CCMSGConnectionRecvFailure eMsg = new CCMSGConnectionRecvFailure(); eMsg.ExceptionInfo = ex.ToString(); lock (RecvQueue) { RecvQueue.Enqueue(new KeyValuePair <int, object>(eMsg.MessageId, eMsg)); } goto BREAK_CONNECT; } BREAK_CONNECT: // when receive action is over, which represents that socket can't receive any data lock (RecvQueue) { if (State == ConnectionState.Established || State == ConnectionState.Disconnecting) // ���״̬��Ϊ���ÿͻ��������Ͽ���������ʱ�� { State = ConnectionState.Closed; var vMsg = new CCMSGConnectionBreak(); RecvQueue.Enqueue(new KeyValuePair <int, object>(vMsg.MessageId, vMsg)); } } }