Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在SocketAsyncEventArgs对象上使用缓冲区_C#_Sockets - Fatal编程技术网

C# 如何在SocketAsyncEventArgs对象上使用缓冲区

C# 如何在SocketAsyncEventArgs对象上使用缓冲区,c#,sockets,C#,Sockets,我们不得不在SocketAsyncEventArgs对象上使用缓冲区 使用旧的套接字方法,我们将强制转换状态对象,如下所示: clientState cs = (clientState)asyncResult.AsyncState; 然而,3.5框架是不同的 对于从客户端以块的形式到达的字符串,我们似乎无法确定缓冲区是如何工作的,因此我们可以在找到char3时处理整个字符串 当前代码: private void ProcessReceive(SocketAsyncEventArgs e) {

我们不得不在SocketAsyncEventArgs对象上使用缓冲区

使用旧的套接字方法,我们将强制转换状态对象,如下所示:

clientState cs = (clientState)asyncResult.AsyncState;
然而,3.5框架是不同的

对于从客户端以块的形式到达的字符串,我们似乎无法确定缓冲区是如何工作的,因此我们可以在找到char3时处理整个字符串

当前代码:

private void ProcessReceive(SocketAsyncEventArgs e)
{
    string content = string.Empty;

    // Check if the remote host closed the connection.
    if (e.BytesTransferred > 0)
    {
        if (e.SocketError == SocketError.Success)
        {
            Socket s = e.UserToken as Socket;
            //asyncResult.AsyncState;

            Int32 bytesTransferred = e.BytesTransferred;

            // Get the message received from the listener.
            content += Encoding.ASCII.GetString(
                e.Buffer, e.Offset, bytesTransferred);

            if (content.IndexOf(Convert.ToString((char)3)) > -1)
            {
                e.BufferList = null;

                // Increment the count of the total bytes receive by the server
                Interlocked.Add(ref this.totalBytesRead, bytesTransferred);
            }
            else
            {
                content += Encoding.ASCII.GetString(
                    e.Buffer, e.Offset, bytesTransferred);
                ProcessReceive(e);
            }
        }
        else
        {
            this.CloseClientSocket(e);
        }
    }
}

首先,我要说我从未使用过.NET3.5Sockets,所以这个答案是一个有根据的猜测

您遇到的问题是,您没有在每次读取时以某种状态存储内容。 所以问题是:
首先

  • 调用ProcessReceive:
    string content=string.Empty

  • 您向内容追加:'content+=Encoding.ASCII.GetString(e.Buffer,e.Offset,ew.bytesttransfered)`

  • 再次调用ProcessReceive:
    string content=string.Empty
  • 循环继续,内容始终设置为空字符串
  • 其次
    要接收调用ProcessReceive的剩余数据,这是不正确的。您需要使用ReceiveAsync对底层套接字进行另一次读取

    我已使用


    您可以使用
    缓冲区
    缓冲区列表
    ,但不能同时使用两者
    如果将缓冲区设置为非空值,并且尝试将BufferList属性设置为非空值,则会引发异常。
    因此在此处将
    BufferList
    设置为
    null
    ,没有意义,因为
    Buffer
    中的任何一个都不是空的,在这种情况下
    BufferList
    无论如何都是空的,或者
    Buffer
    为null,在这种情况下
    GetString
    将已经抛出
    ArgumentNullException
    // You'll need some state object, if you don't already have one
    class AsyncServerState
    {
       public byte[] Buffer = new byte[8192]; // 8K buffer
       public StringBuilder Content = new StringBuilder0; // Place to store the content as it's received
       public SocketAsyncEventArgs ReadEventArgs = new SocketAsyncEventArgs();
       public Socket Client;
    }
    
    // You'll need to setup the state where ever you process your connect
    // something similar to this.
    void Accept_Completed(object sender, SocketAsyncEventArgs e)
    {
        if (e.SocketError == SocketError.Success)
        {
            Socket client = e.AcceptSocket;
            AsyncServerState state = new AsyncServerState();
            state.ReadEventArgs.AcceptSocket = client;
            state.ReadEventArgs.Completed += new EventHandler(                                              IO_Completed);
            state.ReadEventArgs.UserToken = state;
            state.Client = client;
            state.ReadEventArgs.SetBuffer(state.Buffer, 0, state.Buffer.Length);
    
            if (!client.ReceiveAsync(state.ReadEventArgs))
            {   
                // Call completed synchonously
                ProcessReceive(state.ReadEventArgs);
            }
        }
        ProcessAccept(e);
    }
    
    private void ProcessReceive(SocketAsyncEventArgs e)
    {        
        var state = e.UserToken as AsyncServerState;
    
        // Check if the remote host closed the connection.
        if (e.BytesTransferred > 0)
        {
            if (e.SocketError == SocketError.Success)
            {
                // Get the message received from the listener.
                sting content = Encoding.ASCII.GetString(state.Buffer, 0, e.BytesTransferred);
    
                // Append the received data to our state
                state.Content.Append(content);                          
    
                // Increment the count of the total bytes receive by the server
                Interlocked.Add(ref this.totalBytesRead, bytesTransferred);
    
                if (content.IndexOf(Convert.ToString((char)3)) > -1)
                {
                    // Final Message stored in our state
                    string finalContent = state.Content.ToString();
                    return;                
                }
                else
                {
                    // You need to issue another ReceiveAsync, you can't just call ProcessReceive again
                    if (!state.Client.ReceiveAsync(state.ReadEventArgs))
                    {
                        // Call completed synchonously
                        ProcessReceive(state.ReadEventArgs);
                    }                
                }
            }
            else
            {
                this.CloseClientSocket(e);
            }
        }
    }