Ejemplo n.º 1
0
        //阻塞式连接,使用默认Ip端口进行连接
        public ServiceModel.SOCKET_CODE SocketConnect()
        {
            //如果Socket未初始化且不是绑定状态
            if (ServiceModel.BASESOCKET_STATE.SOCKET_INITING != state &&
                ServiceModel.BASESOCKET_STATE.SOCKET_BINDING != state)
            {
                return(ServiceModel.SOCKET_CODE.ERROR_STATE);
            }
            IPAddress addr = IPAddress.Parse(MyCentorl.Ip.Trim());

            try
            {
                //使用默认的端口和地址进行连接
                socket.Connect(addr, MyCentorl.Port);
            }
            catch (Exception e)
            {
                state = ServiceModel.BASESOCKET_STATE.SOCKET_ERROR;
                return(ServiceModel.SOCKET_CODE.ERROR_CONNECT);
            }
            //连接成功更新状态为已连接
            state = ServiceModel.BASESOCKET_STATE.SOCKET_CONNECTING;
            //启动接收
            StartRecv();
            return(ServiceModel.SOCKET_CODE.SUCCESS);
        }
Ejemplo n.º 2
0
        //异步发送数据
        public ServiceModel.SOCKET_CODE SocketSend(byte[] data, int offset, int size)
        {
            //只有以下两种情况可以发送数据
            //1.当我是服务器,我可以对已经连接上我的客户端进行发送数据
            //2.当我是客户端,且已经连接上服务器
            //tcp服务端套接字只能用于接收连接,无法用于发送数据
            if (ServiceModel.BASESOCKET_STATE.SOCKET_CONNECTING != state)
            {
                return(ServiceModel.SOCKET_CODE.ERROR_STATE);
            }

            try
            {
                socket.BeginSend(data, offset, size, SocketFlags.None, new AsyncCallback(OnSend), null);
            }
            //当发生套接字错误,表示该套接字已经出现异常
            catch
            {
                state = ServiceModel.BASESOCKET_STATE.SOCKET_ERROR;
                return(ServiceModel.SOCKET_CODE.ERROR_SOCKET);
            }

            return(ServiceModel.SOCKET_CODE.SUCCESS);
        }
Ejemplo n.º 3
0
        private byte[] backupBuffer = null;         //备份缓冲区,用来缓存半包


        public void NetWork_TCP()
        {
            socket             = new Socket(AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, ProtocolType.Tcp);
            state              = ServiceModel.BASESOCKET_STATE.SOCKET_INITING;
            socket.SendTimeout = 500;
        }
Ejemplo n.º 4
0
        private void OnRecv(IAsyncResult ar)
        {
            try
            {
                int    recvLength = socket.EndReceive(ar);
                int    pkgLength  = 0;
                byte[] data;
                //如果半包数据不为空
                if (null != backupBuffer)
                {
                    //将半包和后面接收到的数据报拼接起来
                    data = backupBuffer.Concat(recvBuffer.Take(recvLength).ToArray()).ToArray();
                }
                else
                {
                    data = recvBuffer.Take(recvLength).ToArray();
                }
                //解决连包问题
                while (true)
                {
                    // 1. recvEvent返回一个完整的数据包长度
                    pkgLength = MyCentorl.RecvMessage(data);

                    if (pkgLength <= 0 || pkgLength > maxPackage)
                    {
                        //出现异常,连接关闭
                        state = ServiceModel.BASESOCKET_STATE.SOCKET_ERROR;
                        Close();
                        break;
                    }

                    // 2. 如果正常处理完,则直接启动下次接收
                    if (pkgLength == data.Length)
                    {
                        ////TraceUtil.Log("正常");
                        backupBuffer = null;
                        Array.Clear(recvBuffer, 0, recvBuffer.Length);
                        pkgLength = 0;
                        break;
                    }
                    // 3. 如果还未接收完,半包则在偏移处等待
                    else if (pkgLength > data.Length)
                    {
                        //将半包数据拷贝到backupBuffer
                        ////TraceUtil.Log("半包");
                        backupBuffer = data.Take(data.Length).ToArray();
                        break;
                    }
                    // 4. 如果是连包,则循环处理
                    else if (pkgLength < data.Length)
                    {
                        //自增偏移量并跳过已经处理的包
                        ////TraceUtil.Log("连包");
                        data         = data.Skip(pkgLength).ToArray();
                        backupBuffer = null;
                    }
                    else
                    {
                        break;
                    }
                }
                StartRecv();
            }
            catch
            {
                state = ServiceModel.BASESOCKET_STATE.SOCKET_ERROR;
                Close();
            }
        }