2013-02-13 108 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