2009-12-03 141 views
6

我仍然試圖改進一點我之前寫的東西。 現在我遇到了接收數據的問題。我有一個程序用於使用tcpClient將字符串發送到Im正在監聽指定端口的程序。它正常工作,所以我決定把更多的時間以C#接收和發送數據

public static void receiveThread() 
{ 
    while (true) 
    { 
     TcpListener tcpListener = new TcpListener(IPAddress.Any, port); 
     tcpListener.Start(); 

     Console.WriteLine("Waiting for connection..."); 

     TcpClient tcpClient = tcpListener.AcceptTcpClient(); 

     Console.WriteLine("Connected with {0}", tcpClient.Client.RemoteEndPoint); 

     while (!(tcpClient.Client.Poll(20, SelectMode.SelectRead))) 
     { 
      NetworkStream networkStream = tcpClient.GetStream(); 
      StreamReader streamReader = new StreamReader(networkStream); 

      data = streamReader.ReadLine(); 

      if (data != null) 
      { 
       Console.WriteLine("Received data: {0}", data); 
       send(data); // Here Im using send Method 
      } 
     } 
     Console.WriteLine("Dissconnected...\n"); 
     tcpListener.Stop(); 
    } 
} 

/// <summary> 
/// Sending data 
/// </summary> 
/// <param name="data">Data to send</param> 
public static void send(string data) 
{ 
    TcpClient tcpClient = new TcpClient(); 
    try 
    { 
     tcpClient.Connect(ipAddress, sendPort); 
     Console.WriteLine("Connected with {0}", tcpClient.Client.RemoteEndPoint); 
    } 
    catch (Exception e) 
    { 
     Console.WriteLine(e); 
    } 
    if (tcpClient.Connected) 
    { 
     NetworkStream networkStream = tcpClient.GetStream(); 
     StreamWriter streamWriter = new StreamWriter(networkStream); 
     Console.WriteLine("Messege {0} to {1}", data, tcpClient.Client.RemoteEndPoint); 
     streamWriter.WriteLine(data); 
     streamWriter.Flush(); 
     tcpClient.Close(); 
    } 
} 

有時它工作正常,但更多的時候,讓我們把它叫做一個接收器,不能得到什麼我試着去發送發送數據。我真的不知道它有什麼問題。看起來像發送方法可能有問題。下面是接收器輸出的一個例子

Waiting for connection... 
Connected with 127.0.0.1:52449 
Dissconnected... 

Waiting for connection... 
Connected with 127.0.0.1:52450 
Received data: qweqwe 
Dissconnected... 

Waiting for connection... 
Connected with 127.0.0.1:52451 
Dissconnected... 

Waiting for connection... 
Connected with 127.0.0.1:52452 
Dissconnected... 

Waiting for connection... 
Connected with 127.0.0.1:52453 
Received data: zxczx 
Dissconnected... 

Waiting for connection... 
Connected with 127.0.0.1:52454 
Dissconnected... 

Waiting for connection... 
Connected with 127.0.0.1:52455 
Received data: aasd 
Dissconnected... 

Waiting for connection... 
Connected with 127.0.0.1:52457 
Received data: www 
Dissconnected... 

回答

1

確保數據實際上追鬼魂之前在流上存在。如果存在ALWAYS數據,我們可以處理這個問題,但是從邏輯上來看,它看起來好像該數據流要麼被清空,要麼只是沒有數據。

+0

看來,這取決於數據有多快進來,而不是每次它可以發送,所以大部分都會丟失。你的回答讓我更加認真地思考:> – Allek

6

幾個問題在這裏:

  1. StreamReader具有4KB的緩衝區,將嘗試在第一次調用讀儘可能以ReadLine()。結果是您可能在StreamReader中有數據,並在沒有更多可用數據時進入Poll(),因爲它已被讀取。
  2. Poll()需要幾微秒。等待0.02ms對於傳入數據很可能會返回false,除非在調用Poll()之前有數據。
  3. 您可以在每次迭代中創建一個新的StreamReader,這可能會丟棄之前已讀取的數據。

如果你只是要讀條線路並想超時和StreamReader,我會做這樣的事情:

delegate string ReadLineDelegate(); 
... 
using (NetworkStream networkStream = tcpClient.GetStream()) { 
    StreamReader reader = new StreamReader(networkStream); 
    ReadLineDelegate rl = new ReadLineDelegate (reader.ReadLine); 
    while (true) { 
     IAsyncResult ares = rl.BeginInvoke (null, null); 
     if (ares.AsyncWaitHandle.WaitOne (100) == false) 
      break; // stop after waiting 100ms 
     string str = rl.EndInvoke (ares); 
     if (str != null) { 
      Console.WriteLine ("Received: {0}", str); 
      send (str); 
     } 
    } 
} 
+0

不知道這裏發生了什麼。我不喜歡它,因爲我願意。你能解釋一點這個嗎?並有沒有其他更好的選擇來接收這些數據併發送它而不使用StreamReader?它是我第一次嘗試寫這樣的東西,所以我不知道什麼更好或更壞 – Allek

+0

上面的代碼所做的是讀取行,直到從服務器端關閉流或直到讀取超過100ms。至於其他讀/寫選項,這取決於你想要做什麼。 「自然」接口是使用字節[]與套接字。 – Gonzalo