private void ProcessMessage(object buffer)
        {
            try
            {
                byte[] data = (byte[])buffer;
                if (!string.IsNullOrWhiteSpace(this.encryKey))
                {
                    data = AesEncryHelper.AesDecrypt(data, this.encryKey);
                }
                Message message = EntityBufCore.DeSerialize <Message>(data);

                if (message.IsMessage(MessageType.NEGOTIATIONENCRYR))
                {
                    var nmsg = message.GetMessageBody <NegotiationEncryMessage>();
                    this.encryKey = Encoding.ASCII.GetString(RsaEncryHelper.RsaDecrypt(Convert.FromBase64String(nmsg.EncryKey), this.rsaRrivateKey));
                    Console.WriteLine("收到加密串:" + encryKey);
                    _startSign.Set();
                }
                else
                {
                    OnMessage(message);
                }
            }
            catch (Exception e)
            {
                OnError(e);
            }
        }
Example #2
0
        void SocketAsyncEventArgs_Completed(object sender, SocketAsyncEventArgs e)
        {
            e.Completed -= SocketAsyncEventArgs_Completed;

            var args = e as IOCPSocketAsyncEventArgs;

            if (args.BytesTransferred == 0 || args.SocketError != SocketError.Success)
            {
                if (SocketApplication.SocketApplicationEnvironment.TraceSocketDataBag)
                {
                    LogManager.LogHelper.Instance.Debug(e.AcceptSocket.Handle + "异常断开:" + args.SocketError);
                }

                RemoveSession(args);
                return;
            }
            else
            {
                bool hasdataerror = false;
                try
                {
                    #region 数据逻辑
                    if (!args.IsReadPackLen)
                    {
                        if (args.BytesTransferred != 4)
                        {
                            throw new Exception("读取长度失败");
                        }
                        var offset = args.BufferIndex == -1 ? 0 : _bufferpoll.GetOffset(args.BufferIndex);

                        var dataLen = BitConverter.ToInt32(e.Buffer, offset);

                        if (SocketApplication.SocketApplicationEnvironment.TraceSocketDataBag)
                        {
                            LogManager.LogHelper.Instance.Debug(e.AcceptSocket.Handle + "准备接收数据:长度" + dataLen, null);
                        }

                        if (dataLen > MaxPackageLength || dataLen <= 0)
                        {
                            throw new SocketSessionDataException(string.Format("数据异常,长度:" + dataLen));
                        }
                        else
                        {
                            args.IsReadPackLen = true;
                            //byte[] readbuffer = new byte[dataLen];
                            args.BufferLen = dataLen;
                            args.BufferRev = 0;
                            //args.SetBuffer(readbuffer, 0, dataLen);


                            SetBuffer(args, 0, dataLen);
                        }
                    }
                    else
                    {
                        if (SocketApplication.SocketApplicationEnvironment.TraceSocketDataBag)
                        {
                            var offset1 = (args.BufferLen == args.Buffer.Length) ? 0 : _bufferpoll.GetOffset(args.BufferIndex);
                            var bytes   = args.Buffer.Skip(offset1 + args.BufferRev).Take(args.BytesTransferred).ToArray();
                            //if (args.BytesTransferred < args.BufferLen)
                            {
                                LogManager.LogHelper.Instance.Debug(string.Format(e.AcceptSocket.Handle + "接收数据{0}/{1}/{2},{3}", args.BufferLen, args.BufferRev, args.BytesTransferred, Convert.ToBase64String(bytes)), null);
                            }
                        }

                        args.BufferRev += args.BytesTransferred;

                        Exception messageError = null;
                        if (args.BufferRev == args.BufferLen)
                        {
                            byte[] bt     = null;
                            var    offset = args.BufferIndex == -1 ? 0 : _bufferpoll.GetOffset(args.BufferIndex);

                            //校验
                            var crc32 = BitConverter.ToInt32(args.Buffer, offset);

                            var calcrc32 = LJC.FrameWork.Comm.HashEncrypt.GetCRC32(args.Buffer, offset + 4, args.BufferLen - 4);
                            if (calcrc32 == crc32)
                            {
                                bt = new byte[args.BufferLen - 4];
                                for (int i = 4; i < args.BufferLen; i++)
                                {
                                    bt[i - 4] = args.Buffer[offset + i];
                                }

                                ThreadPool.QueueUserWorkItem(new WaitCallback((buf) =>
                                {
                                    Session connSession = null;
                                    try
                                    {
                                        Message message = null;

                                        if (_connectSocketDic.TryGetValue(args.UserToken.ToString(), out connSession))
                                        {
                                            if (!string.IsNullOrWhiteSpace(connSession.EncryKey))
                                            {
                                                try
                                                {
                                                    bt = AesEncryHelper.AesDecrypt(bt, connSession.EncryKey);
                                                }
                                                catch (Exception ex)
                                                {
                                                    throw new SocketApplicationException("解密失败", ex);
                                                }
                                            }

                                            try
                                            {
                                                message = EntityBufCore.DeSerialize <Message>(bt);
                                            }
                                            catch (Exception ex)
                                            {
                                                messageError = ex;
                                            }

                                            connSession.LastSessionTime = DateTime.Now;
                                            connSession.BytesRev       += bt.Length;
                                            if (messageError == null)
                                            {
                                                //如果是协商加密的
                                                if (message.IsMessage(MessageType.NEGOTIATIONENCRYR))
                                                {
                                                    var nmsg = message.GetMessageBody <NegotiationEncryMessage>();
                                                    if (string.IsNullOrWhiteSpace(nmsg.PublicKey))
                                                    {
                                                        throw new SocketApplicationException("公钥错误");
                                                    }

                                                    var encrykey = connSession.EncryKey;
                                                    if (string.IsNullOrWhiteSpace(encrykey))
                                                    {
                                                        encrykey = Guid.NewGuid().ToString("N");
                                                        Console.WriteLine("发送加密串:" + encrykey);
                                                        var rep = new Message(MessageType.NEGOTIATIONENCRYR);
                                                        rep.SetMessageBody(nmsg);
                                                        nmsg.EncryKey = Convert.ToBase64String(RsaEncryHelper.RsaEncrypt(Encoding.ASCII.GetBytes(encrykey), nmsg.PublicKey));;
                                                        connSession.SendMessage(rep);

                                                        connSession.EncryKey = encrykey;
                                                    }
                                                    else
                                                    {
                                                        throw new SocketApplicationException("不允许多次协商密钥");
                                                    }
                                                }
                                                else
                                                {
                                                    FromApp(message, connSession);
                                                }
                                            }
                                            else
                                            {
                                                OnError(messageError);
                                            }
                                        }
                                        else
                                        {
                                            OnError(new Exception("取会话失败,args.UserToken=" + args.UserToken));
                                        }
                                    }
                                    catch (SocketApplicationException ex)
                                    {
                                        if (connSession != null)
                                        {
                                            connSession.Close();
                                        }
                                        ex.Data.Add("SessionID", connSession.SessionID);
                                        OnError(ex);
                                    }
                                }), bt);
                            }
                            else
                            {
                                messageError = new Exception("检查校验码出错");
                                messageError.Data.Add("crc32", crc32);
                                messageError.Data.Add("calcrc32", calcrc32);
                                messageError.Data.Add("data", bt == null ? "" : Convert.ToBase64String(bt));

                                //LogManager.LogHelper.Instance.Error("接收数据出错", messageError);

                                Session connSession;
                                if (_connectSocketDic.TryGetValue(args.UserToken.ToString(), out connSession))
                                {
                                    connSession.LastSessionTime = DateTime.Now;
                                    connSession.BytesRev       += args.BufferRev;
                                    OnError(messageError);
                                }
                                else
                                {
                                    OnError(new Exception("取会话失败,args.UserToken=" + args.UserToken));
                                }
                            }

                            args.IsReadPackLen = false;
                            //args.SetBuffer(_bufferpoll.Buffer, _bufferpoll.GetOffset(args.BufferIndex), 4);
                            SetBuffer(args, 0, 4);
                        }
                        else
                        {
                            SetBuffer(args, args.BufferRev, args.BufferLen - args.BufferRev);
                            LogManager.LogHelper.Instance.Debug("e.SetBuffer:" + (args.BufferRev) + ",len:" + (args.BufferLen - args.BufferRev), null);
                        }
                    }
                    #endregion
                }
                catch (SocketSessionDataException ex)
                {
                    RemoveSession(args);
                    hasdataerror = true;
                    OnError(ex);
                }
                catch (Exception ex)
                {
                    OnError(ex);
                }
                finally
                {
                    if (!hasdataerror)
                    {
                        e.Completed += SocketAsyncEventArgs_Completed;
                        if (!e.AcceptSocket.ReceiveAsync(e))
                        {
                            LogManager.LogHelper.Instance.Debug(e.AcceptSocket.Handle + "同步完成,手动处理", null);
                            SocketAsyncEventArgs_Completed(null, e);
                        }
                    }
                }
            }
        }
        public bool StartClient()
        {
            lock (this)
            {
                try
                {
                    if (socketClient != null && socketClient.Connected)
                    {
                        return(true);
                    }

                    if (DateTime.Now.Subtract(lastReStartClientTime).TotalMilliseconds <= reConnectClientTimeInterval)
                    {
                        return(false);
                    }

                    bool isResetClient = false;
                    if (socketClient != null)
                    {
                        socketClient.Close();
                        isResetClient = true;
                    }

                    if (!string.IsNullOrWhiteSpace(encryKey))
                    {
                        encryKey = string.Empty;
                    }

                    socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    socketClient.ReceiveBufferSize = 32000;
                    socketClient.SendBufferSize    = 32000;
                    socketClient.NoDelay           = true;

                    try
                    {
                        if (socketAsyncEvent != null)
                        {
                            socketAsyncEvent.Completed -= socketAsyncEvent_Completed;
                        }

                        IPAddress connectip;
                        if (!string.IsNullOrEmpty(serverIp))
                        {
                            connectip = IPAddress.Parse(serverIp);
                        }
                        else
                        {
                            connectip = IPAddress.Any;
                        }
                        socketAsyncEvent                = new IOCPSocketAsyncEventArgs();
                        socketAsyncEvent.Completed     += socketAsyncEvent_Completed;
                        socketAsyncEvent.RemoteEndPoint = new IPEndPoint(connectip, ipPort);

                        _startSign.Reset();
                        socketClient.ConnectAsync(socketAsyncEvent);
                        _startSign.WaitOne(30 * 1000);

                        if (!socketClient.Connected)
                        {
                            throw new Exception("连接超时");
                        }

                        if (isSecurity)
                        {
                            RsaEncryHelper.GenPair(out rsaPubKey, out rsaRrivateKey);
                            var msg = new Message(MessageType.NEGOTIATIONENCRYR);
                            encryKey = null;
                            _startSign.Reset();
                            msg.SetMessageBody(new NegotiationEncryMessage
                            {
                                PublicKey = rsaPubKey
                            });
                            socketClient.SendMessage(msg, string.Empty);
                            _startSign.WaitOne(30 * 1000);
                            if (string.IsNullOrWhiteSpace(encryKey))
                            {
                                throw new Exception("协商加密失败");
                            }
                        }
                    }
                    catch (SocketException e)
                    {
                        var ne = new Exception(string.Format("连接到远程服务器{0}失败,端口:{1},原因:{2},网络错误号:{3}",
                                                             serverIp, ipPort, e.Message, e.SocketErrorCode));
                        throw ne;
                    }
                    catch (Exception e)
                    {
                        lastReStartClientTime = DateTime.Now;
                        throw e;
                    }

                    isStartClient = true;

                    if (isResetClient && OnClientReset != null)
                    {
                        OnClientReset();
                    }

                    return(true);
                }
                catch (Exception e)
                {
                    //OnError(e);
                    return(false);
                }
            }
        }
Example #4
0
        public bool StartClient()
        {
            if (_isStartingClient)
            {
                return(false);
            }
            _isStartingClient = true;

            try
            {
                if (socketClient != null && socketClient.Connected)
                {
                    return(true);
                }

                bool isResetClient = false;
                if (socketClient != null)
                {
                    try
                    {
                        socketClient.Shutdown(SocketShutdown.Both);
                    }
                    catch
                    {
                    }
                    socketClient.Close();
                    isResetClient = true;
                }

                if (!string.IsNullOrWhiteSpace(encryKey))
                {
                    encryKey = string.Empty;
                }

                socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                socketClient.ReceiveBufferSize = 32000;
                socketClient.SendBufferSize    = 32000;
                socketClient.NoDelay           = true;

                try
                {
                    if (!string.IsNullOrEmpty(ipString))
                    {
                        socketClient.Connect(IPAddress.Parse(ipString), ipPort);
                    }
                    else
                    {
                        socketClient.Connect(IPAddress.Any, ipPort);
                    }

                    if (isSecurity)
                    {
                        RsaEncryHelper.GenPair(out rsaPubKey, out rsaRrivateKey);
                        var msg = new Message(MessageType.NEGOTIATIONENCRYR);
                        encryKey = null;
                        msg.SetMessageBody(new NegotiationEncryMessage
                        {
                            PublicKey = rsaPubKey
                        });
                        _startSign.Reset();
                        socketClient.SendMessage(msg, string.Empty);
                        var buffer = ReceivingNext(socketClient);
                        ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessMessage), buffer);
                        _startSign.WaitOne(30 * 1000);
                        if (string.IsNullOrWhiteSpace(encryKey))
                        {
                            throw new Exception("协商加密失败");
                        }
                    }
                }
                catch (SocketException e)
                {
                    var ne = new Exception(string.Format("连接到远程服务器{0}失败,端口:{1},原因:{2},网络错误号:{3}",
                                                         ipString, ipPort, e.Message, e.SocketErrorCode));
                    throw ne;
                }
                catch (Exception e)
                {
                    throw e;
                }

                if (!isStartClient && listeningThread == null)
                {
                    listeningThread = new Thread(Receiving);
                    listeningThread.Start();
                }

                isStartClient = true;

                if (isResetClient && OnClientReset != null)
                {
                    OnClientReset();
                }

                return(true);
            }
            catch (Exception e)
            {
                //OnError(e);
                //LogManager.LogHelper.Instance.Error("StartClient error", e);

                return(false);
            }
            finally
            {
                _isStartingClient = false;
            }
        }