C# 网络陌生感

C# 网络陌生感,c#,networking,C#,Networking,我正在开发一个小型网络服务器,我正在使用MonoDevelop的最新版本 我有一个方法PlayerReadLoop,它传递了一个普通的Player对象,还传递了一个tcpClient对象。此方法尚未完成,并且不依赖于所传递的播放器对象,因此,无需提供任何有关播放器的信息。TcpClient绝对是正确初始化的,正如我在过去成功地通过该TcpClient发送消息一样 方法如下: private void playerReadLoop(Player p, TcpClient c) { byte

我正在开发一个小型网络服务器,我正在使用MonoDevelop的最新版本

我有一个方法PlayerReadLoop,它传递了一个普通的Player对象,还传递了一个tcpClient对象。此方法尚未完成,并且不依赖于所传递的播放器对象,因此,无需提供任何有关播放器的信息。TcpClient绝对是正确初始化的,正如我在过去成功地通过该TcpClient发送消息一样

方法如下:

private void playerReadLoop(Player p, TcpClient c)
{
    byte[] message = new byte[4096];
    int bytesRead;
    NetworkStream clientStream = c.GetStream();
    while (true)
    {
        bytesRead = 0;
        try
        {
            bytesRead = clientStream.Read(message, 0, 4096);
        }
        catch
        {
            Console.WriteLine("ERROR");
            break;
        }
        if (bytesRead == 0)
        {
            Console.WriteLine("Disconnected");
            break;
        }

        ASCIIEncoding encoder = new ASCIIEncoding();
        Console.WriteLine(encoder.GetString(message, 0, bytesRead));

    }
}
由于某些原因,上述代码不起作用!你看,

当我环绕这两条线时:

SCIIEncoding encoder = new ASCIIEncoding();
Console.WriteLine(encoder.GetString(message, 0, bytesRead));

使用表示法,无论我的客户端是否发送消息,clientStream.Read都会通过,并返回零字节,表示断开连接。我的客户根本没有发送任何东西,当然也没有断开连接

当这两行没有标记时,clientStream.read永远不会通过。无论我的客户是否发送消息

现在,如果这还不够奇怪,在我的tcpClient初始化之后直接使用上面的代码(与tcpClient初始化的方法相同),代码就可以工作了!我没有对tcpClient做任何事情,我只是将它直接传递给上面的函数,并使用tcpClient初始化一个Player对象。player对象对tcpClient没有任何作用,它只是将其存储在它的一个变量中。我不明白为什么把这段代码放在自己的方法中这样简单的行为会导致行为上的如此恶劣的差异

客户端代码很简单:

TcpClient client = new TcpClient();

IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 21255);

client.Connect(serverEndPoint);

NetworkStream clientStream = client.GetStream();

ASCIIEncoding encoder = new ASCIIEncoding();
byte[] buffer = encoder.GetBytes("Hello Server!");

clientStream.Write(buffer, 0 , buffer.Length);
clientStream.Flush();
我正在一个小型网络服务器上工作

你见过开源的c#network communication library吗?它与即插即用一样好,因此您可以立即启动并运行。另外,您将遇到的大多数问题已经解决。

来源

在网络流上调用Flush没有任何效果,所以它不应该出现在您的代码中

读写操作通常是套接字上的阻塞操作。因此,他们将等待操作完全完成。在读写网络流之前,最好先检查它们是否真的可以被写入或读取。这是有属性的。(更多信息请访问)

另外,因为Read可以返回0,所以这并不意味着客户端像代码中所写的那样“断开连接”。这只是意味着接收缓冲区上还没有可用的字节可供读取。这也意味着默认情况下读取将一直阻塞,直到实际发送数据为止

如果未接收数据,请检查客户端和服务器上的端口和连接设置,使它们匹配

编辑 仅仅因为你在networkstream上写了一些东西,并不意味着它直接通过网络发送。代码和实际套接字之间有一个缓冲区。这个缓冲区没有控制权,只有Windows控制它。这就是为什么有时代码和实际发送之间会有延迟


它还解释了为什么某些设置或代码配置似乎没有直接影响。这些信息隐藏得很好,并不在MSDN上,但是如果你深入研究微软关于套接字通信的technet文档,你会发现更多有趣的地方来解释这一点。不幸的是,我现在无法共享链接。

当我用符号围绕两行时:[……]是什么意思;第2行;变为/*第1行;第2行*/“我的客户端根本没有发送任何东西,当然也没有断开连接。”……但是服务器呢?如何确保该连接的服务器端没有断开您的连接。必须在网络代码故障排除期间运行Wireshark。奇怪的是,当代码在我的执行过程中处于不同的位置时,它可以完美地工作——因此我肯定知道连接信息是正确的,并且检查零字节似乎会导致读取阻塞,直到发送某些内容,或者客户端断开连接,所以,不知道。还有一个事实是,试图从流中读取数据会以某种方式阻止它断开连接!这是一种非常奇怪的行为,但我会尝试在等待流被读取时签出。您对读取流返回0字节的看法是正确的,但没有任何内容可读取!由于某些原因,现在每件事都在工作,我添加了while循环来等待流激活,尽管它们还没有被真正调用。编辑我的帖子,给你一个可能的解释。