Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.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# Socket.EndReceive工作流_C#_Sockets_Tcp - Fatal编程技术网

C# Socket.EndReceive工作流

C# Socket.EndReceive工作流,c#,sockets,tcp,C#,Sockets,Tcp,在上,您可以找到ReadCallback(IAsyncResult) 我不清楚的是这个if/else语句。如果我们已经阅读了一些东西,为什么我们又开始阅读呢 我们为什么不这样做呢 static void ReadCallback(IAsyncResult ar) { StateObject state = (StateObject)ar.AsyncState; Socket handler = state.workSocket; int read = handler.E

在上,您可以找到
ReadCallback(IAsyncResult)

我不清楚的是这个
if/else
语句。如果我们已经阅读了一些东西,为什么我们又开始阅读呢

我们为什么不这样做呢

static void ReadCallback(IAsyncResult ar)
{
    StateObject state = (StateObject)ar.AsyncState;
    Socket handler = state.workSocket;

    int read = handler.EndReceive(ar);

    state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, read));

    if(state.sb.Length > 1)
    {
        string content = state.sb.ToString();

        Console.WriteLine($"Read {content.Length} bytes from socket. \nData: {content}");
    }
    handler.Close();
}

基本上,因为部分消息是一件事

例如,如果您发送1000个字节,那么第一次接收实际上可能只得到30个字节。然后下一个得到70,下一个得到100,然后是50,然后是150,以此类推,直到所有1000字节都被接收到为止(显然,现代网络的数字会更高)。这就是为什么大多数TCP消息都有某种结束标记,或者它们以其大小作为前缀:这样你就知道它们什么时候完成了


请记住:即使您请求100个字节,EndReceive也会提供最多100个字节。它不一定要等到它拥有了所有的字节。

我得到了那个部分,但是
EndReceive
(Socket)怎么知道我再次调用它时他已经收到了多少字节呢?我不确定我是否理解。。。它知道您请求了多少字节以及实际得到了多少字节。但就是这样。单独的请求共享的唯一东西是它们不知道的状态对象。你能重新表述你的问题吗?假设我发送了5个字节。我调用
BeginReceive
,它将字节存储到缓冲区中,但只得到第一个、第二个和第三个字节。在回调函数中,我检查它是否读取了某些内容,如果读取了,我再次调用
BeginReceive
,因为可能有更多的数据,但是现在
BeginReceive
如何知道它需要从字节3开始并继续读取?为什么它不从字节0开始,再读取2-3个字节,然后无限次地执行。相反,它知道它已经读取了3个字节,并从字节3(索引2)开始读取。我是说我明白它的作用,但我想知道怎么做,明白了。每次从EndReceive获取缓冲区时,它都会将其重置。缓冲区被重置,并再次从零开始。因此,您需要在调用之间将数据移出缓冲区,并自行组装。因为你是对的;它不知道。这就是为什么这个例子每次都附加在state.sb后面;因为这是接收到的数据的实际存储库。Microsoft socket教程糟糕透顶。不要从中吸取教训。这段代码是最糟糕的方法。在网上找到一些socket教程,并就什么样的方式看起来最好发展自己的想法。@usr现在就开始做。测试并使用2个控制台应用程序:)我将回答您的悬赏问题。@usr我很高兴,yayy:)
static void ReadCallback(IAsyncResult ar)
{
    StateObject state = (StateObject)ar.AsyncState;
    Socket handler = state.workSocket;

    int read = handler.EndReceive(ar);

    state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, read));

    if(state.sb.Length > 1)
    {
        string content = state.sb.ToString();

        Console.WriteLine($"Read {content.Length} bytes from socket. \nData: {content}");
    }
    handler.Close();
}