在同一端口上重新打开 Tcp 套接字
Reopen Tcp socket on the same port
我有一个用于单一请求-响应目的的套接字。
我将它设置在端口 XXX 上让它等待连接、读取数据并回复一些数据。
我想在同一端口上打开一个新套接字。一旦发送响应。
这是外部处理的(有一个管理器正在检查线程的状态,如果它被使用,它会处理它并创建一个新的。
问题是它在
上被阻止
_socket = _socket.Accept();
并且当新客户端尝试连接时,它永远不会离开此行。 (客户没有得到回复)。
插座是运行在
new Thread(Run);
这是我的 运行 方法:
private void Run()
{
var ipHostInfo = Dns.Resolve(Dns.GetHostName());
var ipAddress = ipHostInfo.AddressList[0];
var localEndPoint = new IPEndPoint(ipAddress, Port);
_socket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
try
{
_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
_socket.Bind(localEndPoint);
_socket.Listen(100);
_socket = _socket.Accept();
var data = string.Empty;
while (true)
{
var bytes = new byte[1024];
var bytesRec = _socket.Receive(bytes);
data += Encoding.UTF8.GetString(bytes, 0, bytesRec);
if (data.IndexOf("<EOF>", StringComparison.Ordinal) <= -1) continue;
var dataWithoutEof = data.Substring(0, data.IndexOf("<EOF>", StringComparison.Ordinal));
//TODO: do smt with the data
break;
}
var byteData = Encoding.UTF8.GetBytes("testResponse" + "<EOF>");
_socket.Send(byteData);
_socket.Shutdown(SocketShutdown.Both);
_socket.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
我想我没有正确关闭现有套接字。
你的代码是错误的,你不应该期望这个方法退出,因为你希望你的服务器在整个过程中 运行ning。我在这里假设您多次调用 运行 。不要那样做。
然后代码变成这样:
_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
_socket.Bind(localEndPoint);
_socket.Listen(100);
while (true)
{
var _servicingsocket = _socket.Accept();
....
_servicingsocket.close();
}
accept 是一个阻塞调用。等待新的连接。
_socket 是一个侦听套接字,必须在服务器的生命周期内保留。
TCP 连接基于套接字对的概念。
服务器启动时,您有一个侦听端口 100 的套接字。
假设建立了一个连接,然后接受 returns 所谓的服务套接字,它基本上是侦听套接字的克隆。这意味着它也使用源端口 100,但因为它是服务套接字,所以它属于标识连接的套接字对。套接字对是 2 个套接字的组合,您自己的套接字和对等套接字。当有数据传入时,TCP 将遍历套接字对以找到正确的套接字。
这样做的另一个好处是,当您处理第一个请求时,您允许其他连接尝试在侦听套接字上排队。您的 _socket 被服务套接字覆盖,然后您假设侦听套接字将被垃圾收集。我不确定这是否会发生,因为我没有像您在代码中那样尝试过,因为这首先是个坏主意,因为它实现了 idisposable。 (https://msdn.microsoft.com/en-us/library/system.net.sockets.socket%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396)如果你真的想关闭服务器,你必须确保关闭服务套接字和监听套接字以使代码干净。
我有一个用于单一请求-响应目的的套接字。
我将它设置在端口 XXX 上让它等待连接、读取数据并回复一些数据。
我想在同一端口上打开一个新套接字。一旦发送响应。
这是外部处理的(有一个管理器正在检查线程的状态,如果它被使用,它会处理它并创建一个新的。
问题是它在
上被阻止_socket = _socket.Accept();
并且当新客户端尝试连接时,它永远不会离开此行。 (客户没有得到回复)。
插座是运行在
new Thread(Run);
这是我的 运行 方法:
private void Run()
{
var ipHostInfo = Dns.Resolve(Dns.GetHostName());
var ipAddress = ipHostInfo.AddressList[0];
var localEndPoint = new IPEndPoint(ipAddress, Port);
_socket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
try
{
_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
_socket.Bind(localEndPoint);
_socket.Listen(100);
_socket = _socket.Accept();
var data = string.Empty;
while (true)
{
var bytes = new byte[1024];
var bytesRec = _socket.Receive(bytes);
data += Encoding.UTF8.GetString(bytes, 0, bytesRec);
if (data.IndexOf("<EOF>", StringComparison.Ordinal) <= -1) continue;
var dataWithoutEof = data.Substring(0, data.IndexOf("<EOF>", StringComparison.Ordinal));
//TODO: do smt with the data
break;
}
var byteData = Encoding.UTF8.GetBytes("testResponse" + "<EOF>");
_socket.Send(byteData);
_socket.Shutdown(SocketShutdown.Both);
_socket.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
我想我没有正确关闭现有套接字。
你的代码是错误的,你不应该期望这个方法退出,因为你希望你的服务器在整个过程中 运行ning。我在这里假设您多次调用 运行 。不要那样做。 然后代码变成这样:
_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
_socket.Bind(localEndPoint);
_socket.Listen(100);
while (true)
{
var _servicingsocket = _socket.Accept();
....
_servicingsocket.close();
}
accept 是一个阻塞调用。等待新的连接。
_socket 是一个侦听套接字,必须在服务器的生命周期内保留。
TCP 连接基于套接字对的概念。
服务器启动时,您有一个侦听端口 100 的套接字。
假设建立了一个连接,然后接受 returns 所谓的服务套接字,它基本上是侦听套接字的克隆。这意味着它也使用源端口 100,但因为它是服务套接字,所以它属于标识连接的套接字对。套接字对是 2 个套接字的组合,您自己的套接字和对等套接字。当有数据传入时,TCP 将遍历套接字对以找到正确的套接字。
这样做的另一个好处是,当您处理第一个请求时,您允许其他连接尝试在侦听套接字上排队。您的 _socket 被服务套接字覆盖,然后您假设侦听套接字将被垃圾收集。我不确定这是否会发生,因为我没有像您在代码中那样尝试过,因为这首先是个坏主意,因为它实现了 idisposable。 (https://msdn.microsoft.com/en-us/library/system.net.sockets.socket%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396)如果你真的想关闭服务器,你必须确保关闭服务套接字和监听套接字以使代码干净。