2013-02-13 73 views
-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(); 
} 
+2

您的读取语句返回读取的字节数。所以如果你成功地读了一些东西,我被设置为一个大于零的数字......而你的while循环是为i <= 0。 – andrew 2013-02-13 02:09:02

+0

这就是我想要的,如果它Read()某事,它会打印一条消息,if不要,只是做一次(我<= 0)。但tstream.Read()只能在第一次正常工作。 – xyloid 2013-02-13 02:39:11

+0

@xlyloid这是因为你只执行一次。再次阅读评论和答案。 – EJP 2013-02-13 02:47:35

回答

2

你之所以只是读取一个字节可以从该行可以看出:

int i = 0; 

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

NetworkStream.Read返回从套接字读取的字节数。所以,只要您收到超过1个字节,您就会终止循环。

这就是说,我可以看到你的代码有多个问题,比如你如何编写循环来从套接字读取字节(为什么在这里嵌套循环?),你如何打印结果接收到的字节(您正在连续打印t,这意味着您将得到“0”),尤其是如何在操作完成后关闭套接字。另外,如果您使用的是Winforms(因为这是Click事件的一部分),使用backgroundworker可能对您的情况更好。

我建议你阅读几个如何正确完成套接字编程的例子,例如从this site

+0

非常感谢你,我正在使用WPF编写这个程序,我打算在当前步骤正常工作时添加你说的内容。当我调试它时,循环不会终止。我在while(i <= 1)中设置断点。 0),当程序停在那里时,我每次执行一条语句,当第一条消息到来时,它将执行Read(),然后执行WriteLine(),但是当第二条消息到达时,它也会执行Read(),那么它将显示WPF窗口而不是执行WriteLine(),我无法理解发生了什么。 – xyloid 2013-02-13 02:36:54

+0

我不在这里关闭套接字,因为我想在anthor单击事件中关闭它。 – xyloid 2013-02-13 02:42:44

+0

@xlyoid如果您得到零,您必须关闭套接字。没有什么可以用它做。 – EJP 2013-02-13 02:46:41

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; 
      } 
     } 

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

或者这可能是因为你永久覆盖了数组ReadBuffer的位置0-39而不对数据做任何处理。

这一切都取决于你的意思是“消息”。

+0

我在这里要做的是:当我<= 0时,程序会尝试读取,如果我> 0这意味着它读取了某事物,它会写入一条消息来签名它发生的事情。 – xyloid 2013-02-13 02:23:03

+0

对不起我的错误,我误按输入 – xyloid 2013-02-13 02:41:18

+0

目前我不在乎覆盖ReadBuffer,我只是希望它显示一条消息,每次它读取sth.Is存在一个方法的工作如下:1接受连接.2读/写几次。3关闭连接? – xyloid 2013-02-13 03:48:43