-1

大家,我正在尝试编写一个循环来从后台线程中连接的套接字中读取。但它只接收第一条消息。我已经搜索了一段时间以找到原因。但还是想不通。我知道有些人遇到了同样的问题。然而,他们的原因似乎不同。我希望有人能帮助我。

private void setPort_Click(object sender, EventArgs e)
{
    SetupTcpListener = new Task(() =>
    {
        try
        {
            Int32 Port;
            Int32.TryParse(portNum.Text, out Port);
            IPAddress localAddr = IPAddress.Parse("127.0.0.1");
            server = new TcpListener(localAddr, Port);

            server.Start(10);
            Tclient = server.AcceptTcpClient();
            Console.WriteLine("Connected");
        }
        catch (SocketException exc)
        {
            Console.WriteLine("SocketException: {0}", exc);
        }
        NetworkStream tstream = Tclient.GetStream();

        int t = 0;
        while (true)//the first loop: WriteLine a signal when read sth
        //read first message:"Get 0"
        //read second message:"Get 1"
        //and so on
        {
            t++;

            int i = 0;

            while (i <= 0)//the second loop is trying to read until get sth.
            //when it get sth, the first while loop continue,and print a "Get t"
            //t means how many times it has read a messsage.
            {
                i = tstream.Read(ReadBuffer,0,40);
            }
            Console.WriteLine("Get "+ t.ToString());
        }
    });
    SetupTcpListener.Start();
}
4

2 回答 2

2

从这一行可以看出您只读取一个字节的原因:

int i = 0;

while (i <= 0)
{
    i = tstream.Read(ReadBuffer,0,40);
}

NetworkStream.Read 返回从套接字读取的字节数。因此,只要您收到超过 1 个字节,您就会退出循环。

话虽如此,我可以看到您的代码存在多个问题,例如您如何编写循环以从套接字读取字节(为什么要在此处嵌套循环?),如何打印接收到的字节的结果(您正在连续打印 t,这意味着您将得到“0”),尤其是在操作完成后您如何不关闭套接字。

此外,如果您使用的是 Winforms(因为这是点击事件的一部分),则使用 backgroundworker 可能更适合您的情况。

我建议您阅读几个有关如何正确完成套接字编程的示例,例如来自此站点的示例。

于 2013-02-13T02:19:26.153 回答
2

这很奇怪:

       while (true)
        {
            t++;

            int i = 0;

            while (i <= 0)
            {
                i = tstream.Read(ReadBuffer,0,40); //now i>0 so quit the loop
            }
            Console.WriteLine("Get "+ t.ToString());
            //but go around again anyway???
        }

你的意思:

       while (true)
        {
            var amtRead = tstream.Read(ReadBuffer,0,40);

            //or even safer
            //var amtRead = tstream.Read(ReadBuffer, 0, ReadBuffer.Length);

            if(amtRead == 0)
            {
                //other end is out of data. transfer is finished
                break;
            }
        }

?

或者也许是你只接受一次连接。

或者可能是因为您永久覆盖数组的位置 0-39ReadBuffer而不对数据做任何事情。

这完全取决于您所说的“消息”是什么意思。

于 2013-02-13T02:19:38.710 回答