当前位置:编程学习 > C#/ASP.NET >>

c# socket异步通信的问题

    是从MSDN的异步通信示例上改的。
    但客户端连接成功后,再发送数据,服务器就没响应了,因为在服务器监听到客户端连接后就进入异步接收状态,收到数据后就进入异步发送(发送消息到客户端)状态,然后就关闭(shutdown和close)了socket,因此当客户端在次发送数据时,服务器没响应。但是我改了半天,还是没能解决此问题,望高手指点 --------------------编程问答-------------------- 异步的完成最后,再次开异步接受数据。。。。。。。

你没看懂msdn的例子。网上这种例子和框架很多呢。 --------------------编程问答--------------------

/// <summary>
        /// 接受数据完成处理函数,异步的特性就体现在这个函数中,
        /// 收到数据后,会自动解析为字符串报文
        /// </summary>
        /// <param name="iar">目标客户端Socket</param>
        protected virtual void ReceiveData(IAsyncResult iar)
        {
            Socket client = (Socket)iar.AsyncState;

            try
            {
                //如果两次开始了异步的接收,所以当客户端退出的时候
                //会两次执行EndReceive

                int recv = client.EndReceive(iar);

                if (recv == 0)
                {
                    //正常的关闭
                    CloseClient(client, Session.ExitType.NormalExit);
                    return;
                }

                string receivedData = _coder.GetEncodingString(_recvDataBuffer, recv);

                //发布收到数据的事件
                if (RecvData != null)
                {
                    Session sendDataSession = FindSession(client);

                    Debug.Assert(sendDataSession != null);

                    //如果定义了报文的尾标记,需要处理报文的多种情况
                    if (_resolver != null)
                    {
                        if (sendDataSession.Datagram != null &&
                         sendDataSession.Datagram.Length != 0)
                        {
                            //加上最后一次通讯剩余的报文片断
                            receivedData = sendDataSession.Datagram + receivedData;
                        }

                        string[] recvDatagrams = _resolver.Resolve(ref receivedData);


                        foreach (string newDatagram in recvDatagrams)
                        {
                            //深拷贝,为了保持Datagram的对立性
                            ICloneable copySession = (ICloneable)sendDataSession;

                            Session clientSession = (Session)copySession.Clone();

                            clientSession.Datagram = newDatagram;
                            //发布一个报文消息
                            RecvData(this, new NetEventArgs(clientSession));
                        }

                        //剩余的代码片断,下次接收的时候使用
                        sendDataSession.Datagram = receivedData;

                        if (sendDataSession.Datagram.Length > MaxDatagramSize)
                        {
                            sendDataSession.Datagram = null;
                        }

                    }
                    //没有定义报文的尾标记,直接交给消息订阅者使用
                    else
                    {
                        ICloneable copySession = (ICloneable)sendDataSession;

                        Session clientSession = (Session)copySession.Clone();

                        clientSession.Datagram = receivedData;

                        RecvData(this, new NetEventArgs(clientSession));
                    }

                }//end of if(RecvData!=null)

                //********************继续接收来自来客户端的数据**********
                client.BeginReceive(_recvDataBuffer, 0, _recvDataBuffer.Length, SocketFlags.None,
                 new AsyncCallback(ReceiveData), client);

            }
            catch (SocketException ex)
            {
                //客户端退出
                if (10054 == ex.ErrorCode)
                {
                    //客户端强制关闭
                    CloseClient(client, Session.ExitType.ExceptionExit);
                }

            }
            catch (ObjectDisposedException ex)
            {
                //这里的实现不够优雅
                //当调用CloseSession()时,会结束数据接收,但是数据接收
                //处理中会调用int recv = client.EndReceive(iar);
                //就访问了CloseSession()已经处置的对象
                //我想这样的实现方法也是无伤大雅的.
                if (ex != null)
                {
                    ex = null;
                    //DoNothing;
                }
            }

        }
--------------------编程问答-------------------- 学习! --------------------编程问答-------------------- 我这的异步接收函数是这样的
 private static void ReadCallback(IAsyncResult ar)
        {
            try
            {
                String content = String.Empty;

                // 【从异步状态对象中获取状态对象进行socket操作】Retrieve the state object and the handler socket from the asynchronous state object.
                StateObject state = (StateObject)ar.AsyncState;
                Socket handler = state.workSocket;


                // 【从客户端socket读出数据】Read data from the client socket. 
                int bytesRead = handler.EndReceive(ar);

                if (bytesRead > 0)
                {
                    // 【数据可能很大,持续累加保存接收到的数据】There  might be more data, so store the data received so far.
                    state.sb.Append(Encoding.UTF8.GetString(state.buffer, 0, bytesRead));

                    // 【如果没有检查文件末尾标签<EOF>,则继续读取数据】Check for end-of-file tag. If it is not there, read 
                    // more data.
                    content = state.sb.ToString();
                    if (content.IndexOf("<EOF>") > -1)
                    {
                        // 【将所有从客户端读出的数据显示到控制台上】All the data has been read from the 
                        // client. Display it on the console.
                        Console.WriteLine("Read {0} bytes from socket. \n Data : {1}", content.Length, content);
                        // 【回复客户端】Echo the data back to the client.
                        content = "[来自服务器的消息]:" + AnalyseData.Fun_GetReturnData(content);
                        Send(handler, content);//向客户端发送消息
                    }
                    else
                    {
                        // 【没有获取所有数据,继续获取】Not all data received. Get more.
                        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
                    }
                }

            }
            catch (Exception Ex)
            {
                Console.WriteLine("方法 ReadCallback 异常:" + Ex.Message.ToString());
            }
        }
--------------------编程问答-------------------- 学习着...
补充:.NET技术 ,  C#
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,