/// <summary> /// Initialize net component and connect to remote server. /// </summary> /// <param name="remoteAddress">The address of remote server to connect.</param> /// <param name="remotePort">The port of remote server to connect.</param> public Boolean Initialize(String remoteAddress, Int32 remotePort) { // �ͻ��˴���IPV6��ʱ��������Ҫ�õ� #if UNITY_5_3_OR_NEWER if (Application.platform == RuntimePlatform.IPhonePlayer) { String newServerIp = ""; AddressFamily newAddressFamily = AddressFamily.InterNetwork; getIPType(remoteAddress, remotePort.ToString(), out newServerIp, out newAddressFamily); if (!string.IsNullOrEmpty(newServerIp)) { remoteAddress = newServerIp; } } #endif // analyze the ip address and port info IPAddress myIp; if (IPAddress.TryParse(remoteAddress, out myIp)) { //strMsg = String.Format("BuildPeer TryParse {0} success", remoteAddress); //Debug.WriteLine(strMsg); m_ipEndPoint = new IPEndPoint(myIp, remotePort); } else { //strMsg = String.Format("BuildPeer GetHostEntry {0} fail", remoteAddress); //Debug.WriteLine(strMsg); return(false); } // Do some cleanup if necessery if (State != ConnectionState.None) { Close(); } // Clean all messages of last connection RecvQueue.Clear(); // Clean all event args of last connection m_connEventArg = new SocketAsyncEventArgs(); m_receiveEventArg = new SocketAsyncEventArgs(); // init event args m_connEventArg.Completed += new EventHandler <SocketAsyncEventArgs>(OnCompletedForConnect); m_connEventArg.RemoteEndPoint = m_ipEndPoint; m_receiveEventArg.Completed += new EventHandler <SocketAsyncEventArgs>(OnCompletedForReceive); m_receiveEventArg.SetBuffer(new byte[ProtoConst.MAX_PACKAGE_LENGTH], 0, ProtoConst.MAX_PACKAGE_LENGTH); // Change state State = ConnectionState.Connecting; // Create work resource RecvCache = new MessageBlock((int)ConnectionConst.CACHE_MAX_BYTE); StartConnectionWork(); return(true); }
//The callback of BeginSend on fuction "SendMessage" private void OnCompletedForSendImpl(SocketAsyncEventArgs e) { try { if (e.SocketError == SocketError.Success) { return; } else//发生故障了 就抛一个异常进行处理 { throw new Exception("The result of SendAsync is not correct"); } } catch (Exception ex) { // Client exception means connection is disconnected CCMSGConnectionSendFailure failureMsg = new CCMSGConnectionSendFailure(); failureMsg.ExceptionInfo = ex.ToString(); lock (RecvQueue) { RecvQueue.Enqueue(new KeyValuePair <int, object>(failureMsg.MessageId, failureMsg)); } goto BREAK_CONNECT; } BREAK_CONNECT: lock (RecvQueue) { if (State == ConnectionState.Established) { State = ConnectionState.Closed; var vMsg = new CCMSGConnectionBreak(); RecvQueue.Enqueue(new KeyValuePair <int, object>(vMsg.MessageId, vMsg)); } } }
public async Task Stop() { await _group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)); // RecvQueue.Clear(); SendQueue.Clear(); }
private void Setup(uint sequenceNumber, uint acknowlegementNumber) { this.send_queue = new SendQueue(acknowlegementNumber, Socket.packet_size); this.recv_queue = new RecvQueue(sequenceNumber, 1); this.byte_queue = new ByteQueue(); this.OnConnect(); }
///// <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; } }
/// <summary> /// Get underline protocol message. /// </summary> /// <returns>If exist message return it ,or reutrn null.</returns> public KeyValuePair <int, object> GetMessagePair() { KeyValuePair <int, object> msgPair = new KeyValuePair <int, object>(0, null); lock (RecvQueue) { if (RecvQueue.Count > 0) { var vMsg = RecvQueue.Dequeue(); return(vMsg); } } return(msgPair); }
Task recvProcess() => Task.Run(async() => { var knownPackets = new List <Tuple <ErebusAddress, long> >(); Log.RecordEvent(this, $"Receive process started for instance at {Address}.", LogEntrySeverity.Info); while (process) { try { if (RecvTSM.RunSafe(() => { if (RecvQueue.Count > 0) { var p = RecvQueue.Dequeue(); Log.RecordEvent(this, $"Received packet {p.Identifier} from {p.Source} to {p.Destination} on port {p.Port} ({p.Data.Length} bytes)", LogEntrySeverity.Info); if (knownPackets.Contains(Tuple.Create(p.Source, p.Identifier))) { return(false); } if (p.Destination == Address || p.Destination == ErebusAddress.Broadcast) { switch (p.Port >> 14) { case 0: Task.Run(() => RawProtocolBase.HandlePacket(p, this)); break; case 1: Task.Run(() => BCPProtocolBase.HandlePacket(p, this)); break; } } if (p.Destination != Address) { SendTSM.RunSafe(() => SendQueue.Enqueue(p)); } knownPackets.Add(Tuple.Create(p.Source, p.Identifier)); return(false); } return(true); })) { await Task.Delay(5); } } catch (Exception e) { Log.RecordEvent(this, $"Exception in main instance receive thread: {e.Message}", LogEntrySeverity.Warning); } } });
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; }
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)); } } }
private async void Start(string serverIp, short serverPort) { Func <RT_MSG_TYPE, CipherContext, ICipher> getCipher = (id, context) => { switch (context) { case CipherContext.RC_CLIENT_SESSION: return(_sessionCipher); case CipherContext.RSA_AUTH: return(AuthKey); default: return(null); } }; _group = new MultithreadEventLoopGroup(); _scertHandler = new ScertServerHandler(); // Initialize on connect _scertHandler.OnChannelActive += async(channel) => { RecvQueue.Clear(); SendQueue.Clear(); State = ClientState.CONNECTED; await OnConnected(channel); }; // _scertHandler.OnChannelInactive += async(channel) => { await OnDisconnected(channel); }; // Queue all incoming messages _scertHandler.OnChannelMessage += (channel, message) => { RecvQueue.Enqueue(message); // Log if id is set if (message.CanLog()) { Logger.Info($"RECV {channel}: {message}"); } }; try { var bootstrap = new Bootstrap(); bootstrap .Group(_group) .Channel <TcpSocketChannel>() .Option(ChannelOption.TcpNodelay, true) .Handler(new ActionChannelInitializer <ISocketChannel>(channel => { IChannelPipeline pipeline = channel.Pipeline; pipeline.AddLast(new ScertEncoder()); pipeline.AddLast(new ScertIEnumerableEncoder()); pipeline.AddLast(new ScertTcpFrameDecoder(DotNetty.Buffers.ByteOrder.LittleEndian, Constants.MEDIUS_MESSAGE_MAXLEN, 1, 2, 0, 0, false)); pipeline.AddLast(new ScertDecoder(_sessionCipher, AuthKey)); pipeline.AddLast(_scertHandler); })); try { _boundChannel = await bootstrap.ConnectAsync(new IPEndPoint(IPAddress.Parse(serverIp), serverPort)); } catch (Exception e) { Logger.Error($"Failed to connect to server {e}"); State = ClientState.DISCONNECTED; return; } } finally { } }