我有一个套接字,用于单个请求 - 响应目的。
我在端口XXX上设置它让它等待连接,读取数据并回复一些数据。
我想在同一个端口上打开一个新套接字。一旦发送了回复。
这是在外部处理的(有一个管理员正在检查线程的状态,如果使用它,它会处理它并创建一个新线程。
问题是它在
上被阻止了_socket = _socket.Accept();
当新客户端尝试连接时,它永远不会离开此行。 (并且客户没有回复)。
套接字正在
中运行new Thread(Run);
这是我的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());
}
}
我想我没有正确关闭现有套接字。
答案 0 :(得分:1)
您的代码错误,您不应期望此方法退出,因为您希望服务器一直运行并运行。我在这里假设你多次打电话。不要那样做。 代码变成这样的东西:
_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
_socket.Bind(localEndPoint);
_socket.Listen(100);
while (true)
{
var _servicingsocket = _socket.Accept();
....
_servicingsocket.close();
}
接受是一个阻止通话。等待新的连接。
_socket是一个侦听套接字,必须在服务器的生命周期内保留。
TCP连接基于套接字对的概念 当服务器启动时,您有一个侦听端口100的插槽。 假设建立了连接,然后accept返回所谓的服务套接字,该套接字基本上是来自侦听套接字的克隆。这意味着它也使用源端口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)如果你真的想要关闭服务器,你必须确保关闭服务套接字和监听套接字以使代码干净。