在C#中接收和发送数据
我还在努力提高我之前写的一点点。 现在我遇到了接收数据的问题。 我有一个程序,我用它来发送字符串使用tcpClient到一个程序,我在其中侦听指定的端口。 它工作正常,所以我决定再向前发送数据
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(); } } /// /// Sending data /// /// Data to send 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(); } }
有时它工作正常,但更常见的是,我们称之为接收器,无法得到我想发送的东西。 我真的不知道它有什么问题。 看起来send方法可能有问题。 这是接收器输出的示例
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...
这里有几个问题:
-
StreamReader
有一个4kB缓冲区,在第一次调用ReadLine()
会尝试尽可能多地读取。 结果是,当没有更多数据可用时,您可能在StreamReader中有数据并进入Poll(),因为它已被读取。 -
Poll()
需要几微秒。 除非在调用Poll()
之前数据存在,否则等待0.02ms的传入数据可能会返回false。 - 您可以在每次迭代时创建一个新的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); } } }
在追逐鬼魂之前,确保数据实际存在于流上。 如果有ALWAYS数据我们可以解决问题,但是从逻辑上看它看起来好像流被淘汰或者它上面没有数据。