C# TCPClient在向TCPListener发送消息后运行超时
我想创建一个.NET核心TCP服务器来侦听传入的消息。我创建了一个小类用于测试:C# TCPClient在向TCPListener发送消息后运行超时,c#,.net-core,tcplistener,C#,.net Core,Tcplistener,我想创建一个.NET核心TCP服务器来侦听传入的消息。我创建了一个小类用于测试: internal class TCPServer { private readonly TcpListener tcpListener; public TCPServer() { tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 1234); } public asy
internal class TCPServer
{
private readonly TcpListener tcpListener;
public TCPServer()
{
tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 1234);
}
public async Task Start()
{
tcpListener.Start();
while (true)
{
TcpClient tcpClient = await tcpListener.AcceptTcpClientAsync();
NetworkStream networkStream = tcpClient.GetStream();
byte[] messageBuffer = new byte[tcpClient.ReceiveBufferSize];
int bytesRead = networkStream.Read(messageBuffer, 0, tcpClient.ReceiveBufferSize);
string dataReceived = Encoding.ASCII.GetString(messageBuffer, 0, bytesRead);
Console.WriteLine("Message from tcp client: " + dataReceived);
}
}
}
向该侦听器发送消息时,客户端本身会超时。正如你在这里看到的
我试图通过添加这一行来解决它
tcpClient.Close();
但是我得到了这个错误
如何向该服务器发送消息而不出错?如何启动测试服务器?您是否检查了1234端口是否已打开?我建议通过“telnet 127.0.0.1 1234”进行检查 如果是,你能分享客户的代码吗 如果没有,您能否共享启动服务器的代码? 我试着通过上面的代码运行它,它作为客户机使用telnet工具运行得非常好
class Program
{
static void Main(string[] args)
{
TCPServer server = new TCPServer();
Console.WriteLine("Starting...");
server.Start();
Console.WriteLine("Done.");
Console.WriteLine("Press any key to quit.");
Console.ReadKey();
}
}
internal class TCPServer
{
private readonly TcpListener tcpListener;
public TCPServer()
{
tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 1234);
}
public async Task Start()
{
tcpListener.Start();
try
{
while (true)
{
TcpClient tcpClient = await tcpListener.AcceptTcpClientAsync();
NetworkStream networkStream = tcpClient.GetStream();
byte[] messageBuffer = new byte[tcpClient.ReceiveBufferSize];
int bytesRead = networkStream.Read(messageBuffer, 0, tcpClient.ReceiveBufferSize);
string dataReceived = Encoding.ASCII.GetString(messageBuffer, 0, bytesRead);
Console.WriteLine("Message from tcp client: " + dataReceived);
}
}
finally
{
tcpListener.Stop();
}
}
}
问题是您在循环中处理了客户机套接字。一旦建立了客户机套接字,就需要保持该套接字的活动状态 这不是正确的“服务器”代码,但它将向您展示我的意思并解决您的问题:
while (true)
{
var tcpClient = await tcpListener.AcceptTcpClientAsync();
while(true){
var messageBuffer = new byte[4096];
Console.WriteLine("Waiting for data...");
int bytesRead;
try
{
bytesRead = tcpClient.GetStream().Read(messageBuffer, 0, messageBuffer.Length);
}catch{ break; } // disconnected
var dataReceived = Encoding.ASCII.GetString(messageBuffer, 0, bytesRead);
Console.WriteLine($"Message from tcp client ({bytesRead} bytes): {dataReceived}");
}
}
此解决方案可以实现这一点,但不能同时将多个客户端连接到服务器。为了做到这一点,您需要使用TPL,或者在最坏的情况下,为每个客户机创建一个线程
请看一下/
EndRead
以了解我的意思。TCP是健壮的,因为每条消息都会收到一个ACK,并且当没有收到ACK时,消息会根据设置自动重新发送3到5次。超时表示未收到ACK。30秒后超时,可能每5秒重试5次,30秒后连接关闭。看起来客户端发送了消息,然后在服务器收到消息之前关闭。客户端不应该关闭。所以您认为代码很好,客户端工具不应该关闭客户端?我认为如果客户端在发送数据后立即关闭,可能会出现争用情况。服务器可能无法获取所有数据,然后由于TCP重试而导致超时。这不会解决问题,您只是将问题转移到了任务中
我只是想强调一下,这可能是Olaf启动服务器的方式有问题。例如,wait server.Start();异步静态void Main内部的调用导致代码出现问题。