TCP客户端C#等待新数据可用
我尝试使用tcpclient从tcp服务器检索数据,发送请求并接收响应,除了一件事,它工作正常。 当我尝试多次使用networkstream.readasync,然后再使用networkstream.writeasync时,readasync函数读取上一个writeasync的上一个响应,而不是上一个。要解决这个问题,我必须在读取之前设置一个超时。有没有办法不设置超时,而是等待新数据可用 伪代码示例:TCP客户端C#等待新数据可用,c#,sockets,asynchronous,tcpclient,C#,Sockets,Asynchronous,Tcpclient,我尝试使用tcpclient从tcp服务器检索数据,发送请求并接收响应,除了一件事,它工作正常。 当我尝试多次使用networkstream.readasync,然后再使用networkstream.writeasync时,readasync函数读取上一个writeasync的上一个响应,而不是上一个。要解决这个问题,我必须在读取之前设置一个超时。有没有办法不设置超时,而是等待新数据可用 伪代码示例: connectasync(host,port); //reads a hello messag
connectasync(host,port);
//reads a hello message from the server
networkstram.readasync();
//sending a request to the server
networkstram.writeasync();
//reads again the hello message from the previous read
//not the response from the previously sended writeasync
networkstram.readasync()
伪代码解决方案:
connectasync(host,port);
//reads a hello message from the server
networkstram.readasync();
//sending a request to the server
networkstram.writeasync();
//wait for 1 second
wait(1000)
//reads correctly
networkstram.readasync()
如果您有更好的方法来等待新的可用数据,而不是使用固定超时,请告诉我。
多谢各位
更新
注意:我甚至尝试了同步版本的读写操作,但仍然相同。
我只是使用异步来不阻塞用户界面
public async Task<string> sendQuery()
{
try
{
client.Connect(ConfigParameters.ip, ConfigParameters.port);
if (client.Connected == true)
{
Console.WriteLine("Connected");
var networkStream = client.GetStream();
// Receive data from server
//Receiving HELLO message from the server
byte[] buffer = new byte[1024];
await networkStream.ReadAsync(buffer, 0, buffer.Length);
var serverResponse = Encoding.ASCII.GetString(buffer);
Console.WriteLine("Server: " + serverResponse);
Array.Clear(buffer,0,buffer.Lenght);
Array.Resize(ref buffer, 1024);
// Send data to server
// send query to the server
string data = QueryStore.queryStart+QueryStore.query1.getLRC() + QueryStore.queryEnd;
buffer = System.Text.Encoding.ASCII.GetBytes(data);
await networkStream.WriteAsync(buffer, 0, buffer.Length);
Array.Clear(buffer,0,buffer.Lenght);
Array.Resize(ref buffer, 1024);
// Receive data from server
// receive still HELLO message
buffer = new byte[1024];
await networkStream.ReadAsync(buffer, 0, buffer.Length);
serverResponse = Encoding.ASCII.GetString(buffer);
Console.WriteLine("Server: " + serverResponse);
networkStream.Close();
client.Close();
return "ok";
}
}
catch(SocketException)
{
client.Close();
return "error";
}
finally
{
client.Close();
return "";
}
}
公共异步任务sendQuery()
{
尝试
{
client.Connect(ConfigParameters.ip、ConfigParameters.port);
if(client.Connected==true)
{
控制台。写入线(“连接”);
var networkStream=client.GetStream();
//从服务器接收数据
//从服务器接收HELLO消息
字节[]缓冲区=新字节[1024];
等待networkStream.ReadAsync(buffer,0,buffer.Length);
var serverResponse=Encoding.ASCII.GetString(缓冲区);
Console.WriteLine(“服务器:”+serverResponse);
Array.Clear(buffer,0,buffer.Lenght);
调整数组大小(参考缓冲区,1024);
//向服务器发送数据
//将查询发送到服务器
字符串数据=QueryStore.queryStart+QueryStore.query1.getLRC()+QueryStore.queryEnd;
缓冲区=System.Text.Encoding.ASCII.GetBytes(数据);
等待networkStream.WriteAsync(buffer,0,buffer.Length);
Array.Clear(buffer,0,buffer.Lenght);
调整数组大小(参考缓冲区,1024);
//从服务器接收数据
//仍然收到问候信息
缓冲区=新字节[1024];
等待networkStream.ReadAsync(buffer,0,buffer.Length);
serverResponse=Encoding.ASCII.GetString(缓冲区);
Console.WriteLine(“服务器:”+serverResponse);
networkStream.Close();
client.Close();
返回“ok”;
}
}
捕获(SocketException)
{
client.Close();
返回“错误”;
}
最后
{
client.Close();
返回“”;
}
}
请显示实际代码。您的大纲建议使用同步工作流,那么为什么要使用异步?在async中,您通常在发出新调用之前等待完成-也就是说,您从完成回调发出新调用。看起来您忘记了等待异步操作,因此您可能在WriteAsync
有机会启动之前调用了ReadAsync
。您可能也看到了针对未等待的异步操作的代码分析器警告。发布实际代码我添加了部分实际代码,因为我无法共享完整的代码。数据以最大1500字节的块接收。在多个区块中接收较长的消息,在收到所有区块之前,您无法关闭连接。@jdweng@Panagiotis Kanavos是的,但在我的情况下,服务器每个请求发送一个响应,通常少于1500字节。