【问题标题】:How do I use the Receive Async method with Sockets?如何将 Receive Async 方法与 Sockets 一起使用?
【发布时间】:2015-08-06 20:40:08
【问题描述】:

我正在尝试使用带有套接字的 ReceiveAsync 事件读取数据。我可以成功地将数据发送到服务器,但是当服务器响应时,它没有显示在 SocketAsyncEventArgs 的缓冲区中。我使用 Wireshark 监控流量,我知道响应即将到来,但我的应用程序没有注册它。

接收方法有什么问题?

下面的代码是我认为错误的地方。

buffer = new byte[4096];

SocketAsyncEventArgs args = new SocketAsyncEventArgs();
args.RemoteEndPoint = this._remoteEP;
args.UserToken = this._clientSocket;
args.SetBuffer(buffer, 0, buffer.Length);
this._clientSocket.ReceiveAsync(args);

byte[] udpMsg = new byte[buffer.Length];

Array.Copy(buffer, udpMsg, buffer.Length);

这是整个接收函数。

protected void ProcessReceivedMessages()
{
    byte[] buffer = null;
    int maxSize = AbstractNetworkUtils.GetMaxMessageSize();
    while (!this._isDone)
    {
        Thread.Sleep(1000);
        try
        {
            buffer = new byte[4096];

            SocketAsyncEventArgs args = new SocketAsyncEventArgs();
            args.RemoteEndPoint = this._remoteEP;
            args.UserToken = this._clientSocket;
            args.SetBuffer(buffer, 0, buffer.Length);
            this._clientSocket.ReceiveAsync(args);

            byte[] udpMsg = new byte[buffer.Length];

            Array.Copy(buffer, udpMsg, buffer.Length);  
            //buffer is a byte array of  size 4096 but it is always empty

            byte mType = AbstractCoAPMessage.PeekMessageType(udpMsg);

            if ( (mType == CoAPMessageType.CON ||
                        mType == CoAPMessageType.NON) && AbstractCoAPMessage.PeekIfMessageCodeIsRequestCode(udpMsg))
            {
                //This is a request
                CoAPRequest coapReq = new CoAPRequest();
                coapReq.FromByteStream(udpMsg);
                coapReq.RemoteSender = this._remoteEP;//Setup who sent this message
                string uriHost = ((IPEndPoint)this._remoteEP).Address.ToString();
                UInt16 uriPort = (UInt16)((IPEndPoint)this._remoteEP).Port;

                //setup the default values of host and port
                //setup the default values of host and port
                if (!coapReq.Options.HasOption(CoAPHeaderOption.URI_HOST))
                        coapReq.Options.AddOption(CoAPHeaderOption.URI_HOST, AbstractByteUtils.StringToByteUTF8(uriHost));
                if (!coapReq.Options.HasOption(CoAPHeaderOption.URI_PORT))
                    coapReq.Options.AddOption(CoAPHeaderOption.URI_PORT, AbstractByteUtils.GetBytes(uriPort));

                this.HandleRequestReceived(coapReq);
            }
            else
            {
                //This is a response
                CoAPResponse coapResp = new CoAPResponse();
                coapResp.FromByteStream(udpMsg);
                coapResp.RemoteSender = this._remoteEP;//Setup who sent this message
                //Remove the waiting confirmable message from the timeout queue
                if (coapResp.MessageType.Value == CoAPMessageType.ACK ||
                    coapResp.MessageType.Value == CoAPMessageType.RST)
                {
                    this._msgPendingAckQ.RemoveFromWaitQ(coapResp.ID.Value);
                }
            this.HandleResponseReceived(coapResp);
            }
        }
        catch (SocketException se)
        {
            //Close this client connection
            this._isDone = true;
            this.HandleError(se, null);
        }
        catch (ArgumentNullException argEx)
        {
            this.HandleError(argEx, null);
        }
        catch (ArgumentException argEx)
        {
            this.HandleError(argEx, null);
        }
        catch (CoAPFormatException fEx)
        {
            //Invalid message..
            this.HandleError(fEx, null);
        }                
    }
}

【问题讨论】:

    标签: c# .net sockets silverlight windows-phone-8.1


    【解决方案1】:

    好的,我想通了。我为 args.Completed 添加了一个事件处理程序。

    ...
    SocketAsyncEventArgs args = new SocketAsyncEventArgs();
    args.RemoteEndPoint = this._remoteEP;
    args.SetBuffer(buffer, 0, buffer.Length);
    
    args.Completed += new EventHandler<SocketAsyncEventArgs>(delegate (object s, SocketAsyncEventArgs e)
    {
        if (e.SocketError == SocketError.Success)
        {
            byte[] udpMsg = new byte[e.BytesTransferred];
            // Retrieve the data from the buffer
            Array.Copy(e.Buffer, udpMsg, e.BytesTransferred);
            ...
        }
    });
    this._clientSocket.ReceiveAsync(args);
    ...
    

    这是整个接收函数

    protected void ProcessReceivedMessages()
    {
        byte[] buffer = null;
        int maxSize = AbstractNetworkUtils.GetMaxMessageSize();
        while (!this._isDone)
        {
            Thread.Sleep(1000);
            try
            {
                buffer = new byte[maxSize * 2];
    
                SocketAsyncEventArgs args = new SocketAsyncEventArgs();
                args.RemoteEndPoint = this._remoteEP;
                args.SetBuffer(buffer, 0, buffer.Length);
    
                args.Completed += new EventHandler<SocketAsyncEventArgs>(delegate (object s, SocketAsyncEventArgs e)
                {
                    if (e.SocketError == SocketError.Success)
                    {
                        byte[] udpMsg = new byte[e.BytesTransferred];
                        // Retrieve the data from the buffer
                        Array.Copy(e.Buffer, udpMsg, e.BytesTransferred);
    
                        byte mType = AbstractCoAPMessage.PeekMessageType(udpMsg);
    
                        if ((mType == CoAPMessageType.CON ||
                                mType == CoAPMessageType.NON) && AbstractCoAPMessage.PeekIfMessageCodeIsRequestCode(udpMsg))
                        {
                            //This is a request
                            CoAPRequest coapReq = new CoAPRequest();
                            coapReq.FromByteStream(udpMsg);
                            coapReq.RemoteSender = this._remoteEP;//Setup who sent this message
                            string uriHost = ((IPEndPoint)this._remoteEP).Address.ToString();
                            UInt16 uriPort = (UInt16)((IPEndPoint)this._remoteEP).Port;
    
                            //setup the default values of host and port
                            //setup the default values of host and port
                            if (!coapReq.Options.HasOption(CoAPHeaderOption.URI_HOST))
                                coapReq.Options.AddOption(CoAPHeaderOption.URI_HOST, AbstractByteUtils.StringToByteUTF8(uriHost));
                            if (!coapReq.Options.HasOption(CoAPHeaderOption.URI_PORT))
                                coapReq.Options.AddOption(CoAPHeaderOption.URI_PORT, AbstractByteUtils.GetBytes(uriPort));
    
                            this.HandleRequestReceived(coapReq);
                        }
                        else
                        {
                            //This is a response
                            CoAPResponse coapResp = new CoAPResponse();
                            coapResp.FromByteStream(udpMsg);
                            coapResp.RemoteSender = this._remoteEP;//Setup who sent this message
                                                                    //Remove the waiting confirmable message from the timeout queue
                            if (coapResp.MessageType.Value == CoAPMessageType.ACK ||
                            coapResp.MessageType.Value == CoAPMessageType.RST)
                            {
                                this._msgPendingAckQ.RemoveFromWaitQ(coapResp.ID.Value);
                            }
                            this.HandleResponseReceived(coapResp);
                        }
                    }
                });
                this._clientSocket.ReceiveAsync(args);
            }
            catch (SocketException se)
            {
                //Close this client connection
                this._isDone = true;
                this.HandleError(se, null);
            }
            catch (ArgumentNullException argEx)
            {
                this.HandleError(argEx, null);
            }
            catch (ArgumentException argEx)
            {
                this.HandleError(argEx, null);
            }
            catch (CoAPFormatException fEx)
            {
                //Invalid message..
                this.HandleError(fEx, null);
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-13
      • 1970-01-01
      • 1970-01-01
      • 2014-03-13
      • 2017-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多