问题
The code below reads everything there is to read from tcp client stream, and on the next iteration it will just sit there on the Read() (i'm assuming waiting for data). How can I ensure it doesn't and just returns when there's nothing there to read? Do I have to set low timeout, and respond to an exception when it fails out? Or there's a better way?
TcpClient tcpclnt = new TcpClient();
tcpclnt.Connect(ip, port);
Stream stm = tcpclnt.GetStream();
stm.Write(cmdBuffer, 0, cmdBuffer.Length);
byte[] response = new Byte[2048];
MemoryStream ms = new MemoryStream();
byte[] buffer = new Byte[2048];
int length;
while ((length = stm.Read(buffer, 0, buffer.Length)) > 0)
ms.Write(buffer, 0, length);
byte[] response = ms.ToArray();
tcpclnt.Close();
回答1:
TcpClient has two properties that I would play with.
- NoDelay Gets or sets a value that disables a delay when send or receive buffers are not full.
- ReceiveTimeout Gets or sets the amount of time a TcpClient will wait to receive data once a read operation is initiated
回答2:
Maybe you should use multithreading. One thread should wait for data, another should process received data.
回答3:
Does the server have "Keep Connections Alive" on ?
I have had servers which will send you a stream of empty bytes as long as you request them.
Turning "Keep Connections Alive" stopped it doing this.
回答4:
var socket = new System.Net.Sockets.TcpClient();
socket.NoDelay = true;
socket.Connect(uri.Host, port);
var ns = socket.GetStream();
int timeout = 500; //ms
DateTime lastReceived = DateTime.Now;
string buffer = "";
while (true)
{
if (ns.DataAvailable)
{
var b = ns.ReadByte();
buffer += b + ", "; //customise this line yourself
lastReceived = DateTime.Now;
continue;
}
if (lastReceived.AddMilliseconds(timeout) < DateTime.Now) break;
System.Threading.Thread.Sleep(timeout / 5);
}
来源:https://stackoverflow.com/questions/835549/ensure-streamreader-doesnt-hang-waiting-for-data