我有一个充当 TcpClient 的设备,并将 TCP 数据包发送到我网络上的一组 IP。
当我运行标准 TcpListener 程序(来自官方文档)时,它卡在
server.AcceptTcpClient()
指令中,永远无法实际检测到连接。
我使用 Wireshark 检查数据包是否确实正在发送,事实确实如此。
我已检查数据包是 TCP 并且正在发送 SYN。它们被标记为重复端口,因为它们从未被主机接受。
这是我的代码(从上面的 MS 文档复制并稍加修改)。
public static class Connection
{
public static void Connect(int port)
{
TcpListener server = null;
try
{
IPAddress localAddress = IPAddress.Parse("127.0.0.1");
server = new(localAddress, port);
// Start listening for clients
server.Start();
// Listening loop
while (true)
{
Console.WriteLine("Waiting for connection...");
// Wait for client to connect
TcpClient client = server.AcceptTcpClient(); // NEVER UNBLOCKS
// Close connection
client.Close();
}
}
catch (SocketException e)
{
Console.WriteLine("Socket exception: ", e);
}
finally
{
// Stop listening for clients
server.Stop();
}
}
}
要绑定到传出网络适配器而不是环回,请使用
IPAddress.Any
server = new TcpListener(IPAddress.Any, port);
您还在各个地方错过了
using
,理想情况下您应该使用async
。重复使用相同的缓冲区还可以提高效率。
public static async Task Connect(int port)
{
TcpListener server = null;
try
{
server = new(IPAddress.Any, port);
// Empezar a escuchar peticiones de clientes
server.Start();
// Buffer para leer datos
Byte[] buffer = new Byte[256];
string data = "";
// Entrar al bucle de escucha
while (true)
{
Console.WriteLine("Esperando conexión...");
// Bloquear el programa hasta aceptar una petición
using TcpClient client = await server.AcceptTcpClientAsync();
Console.WriteLine("Conectado!");
data = "";
// Crear una trama para leer y escribir
using NetworkStream stream = client.GetStream();
int i;
// Recibir todos los datos del cliente
while ((i = await stream.ReadAsync(buffer, 0, buffer.Length)) != 0)
{
data = System.Text.Encoding.ASCII.GetString(buffer, 0, i);
Console.WriteLine($"Recibido: {data}");
// Procesar los datos enviados por el cliente
data = data.ToUpper();
i = System.Text.Encoding.ASCII.GetBytes(data, 0, data.Length, buffer, 0);
// Enviar una respuesta
await stream.WriteAsync(buffer, 0, i);
Console.WriteLine($"Devuelto: {data}");
}
// Terminar la conexión
}
}
catch (SocketException e)
{
Console.WriteLine("Socket exception: ", e);
}
finally
{
// Dejar de escuchar clientes
if(server?.Active)
server.Stop();
}
}
请注意,上述代码一次仅处理一个客户端。如果要处理多个,则需要将
TcpClient
交给 Task.Run
任务。