Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/283.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# 如何清空TCP套接字的数据_C#_Sockets_Tcp - Fatal编程技术网

C# 如何清空TCP套接字的数据

C# 如何清空TCP套接字的数据,c#,sockets,tcp,C#,Sockets,Tcp,我实现了一个使用TCP协议的客户机-服务器应用程序。 客户端采用C++实现,不能更改。我正在用c编写服务器端。 在这种情况下,客户机向服务器发送数据,服务器处理数据 在大多数情况下,沟通顺畅 在接收大量数据的情况下,我有以下问题:窗口大小已满,而我只获取部分数据。我跟踪WireShark的通信,它将上一次接收的包标记为[TCP Window full],下一次接收标记为[TCP zero Window] 我理解这里的问题是流大小的限制 尝试增加Socket.ReceiveBufferSize可以

我实现了一个使用TCP协议的客户机-服务器应用程序。 客户端采用C++实现,不能更改。我正在用c编写服务器端。 在这种情况下,客户机向服务器发送数据,服务器处理数据 在大多数情况下,沟通顺畅

在接收大量数据的情况下,我有以下问题:窗口大小已满,而我只获取部分数据。我跟踪WireShark的通信,它将上一次接收的包标记为[TCP Window full],下一次接收标记为[TCP zero Window]

我理解这里的问题是流大小的限制

尝试增加Socket.ReceiveBufferSize可以解决问题,但我不想使用它,因为数据量非常动态,我以前没有办法知道

我正在寻找一种方法,从已读取的接收数据中清空套接字

有人知道怎么做吗

请参阅下面我的代码:

public static void AcceptCallBack(IAsyncResult asyncResult)
{
    allDone.Set();
    Socket listener = (Socket)asyncResult.AsyncState;

    Socket handler = listener.EndAccept(asyncResult); 
    StateObject state = new StateObject();
    state.workSocket = handler;
    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, SocketFlags.None, new AsyncCallback(ReadCallback), state);
}

public static void ReadCallback(IAsyncResult asyncResult)
{
    string content = String.Empty;
    StateObject state = (StateObject)asyncResult.AsyncState;
    Socket handler = state.workSocket;

        if (handler.Connected)
        {
            int bytesRead = handler.EndReceive(asyncResult);
            //Is there a way delete here the read bytes from socket??? 
            if (bytesRead > 0)
            {
                state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
                content = state.sb.ToString();
                XmlDocument doc = new XmlDocument();
                if (/*end of expected data*/)
                {    
                }
                else
                        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, SocketFlags.None, new AsyncCallback(ReadCallback), state);
            }
            else
            {
                handler.Shutdown(SocketShutdown.Both);
                handler.Close();
                allDone.Reset();
                Console.WriteLine("waiting for re-connection...");
                listener.BeginAccept(new AsyncCallback(AcceptCallBack), listener);
            }
        }
        else
        {
            handler.Shutdown(SocketShutdown.Both);
            handler.Close();
        }

}

当缓冲区已满且无法接受更多数据时,通常会出现零窗口。读取数据时,数据将从缓冲区中清除。我知道没有任何方法可以刷新读取缓冲区。读取数据后,窗口将打开并再次接受数据。EndReceive将返回读取到BeginReceive StateObject.BufferSize中所述大小的所有字节,因此需要继续读取。在TCP中,不能保证在一次读取中获得所有数据。您是否跟踪回调并确保在获取所有数据之前继续读取?当然,我有一些读取。您可以看到,如果“/*end of expected data*/”条件为false,我将再次调用handler.BeginReceive。但是在我捕获到缓冲区大小限制后,它不会再次到达那里。我可以标记的另一点是,我的代码中没有异常,我只是看到没有读取所有预期的数据。我会在代码中放入一些控制台写入来调试,或者每次都打印内容变量,问题必须出现在您认为不存在的地方。我敢打赌,if条件没有达到您期望的效果。我不知道如果你没有任何例外,为什么你会认为存在缓冲区问题。该代码基本上与Microsoft的异步示例不同。我无法想象Stringbuilder state.sb有任何限制,因此if条件是唯一其他符合逻辑的地方。非常感谢!我的情况在数据结束前是真实的,是什么阻止了继续阅读。。。因此,未读包在WireShark中被标记为未收到[Zero window]。