【发布时间】:2011-02-18 18:36:00
【问题描述】:
在我制作的测试应用程序中重用服务器套接字时遇到了一些问题。基本上,我有一个同时实现客户端和服务器端的程序。我运行该程序的两个实例以进行测试,一个实例开始托管,另一个实例连接。这是监听代码:
private void Listen_Click(object sender, EventArgs e)
{
try
{
server = new ConnectionWrapper();
HideControls();
alreadyReset = false;
int port = int.Parse(PortHostEdit.Text);
IPEndPoint iep = new IPEndPoint(IPAddress.Any, port);
server.connection.Bind(iep); // bellow explanations refer to this line in particular
server.connection.Listen(1);
server.connection.BeginAccept(new AsyncCallback(OnClientConnected), null);
GameStatus.Text = "Waiting for connections on port " + port.ToString();
}
catch (Exception ex)
{
DispatchError(ex);
}
}
private void OnClientConnected(IAsyncResult iar)
{
try
{
me = Player.XPlayer;
myTurn = true;
server.connection = server.connection.EndAccept(iar); // I will only have one client, so I don't care for the original listening socket.
GameStatus.Text = server.connection.RemoteEndPoint.ToString() + " connected";
StartServerReceive();
}
catch (Exception ex)
{
DispatchError(ex);
}
}
这第一次运行良好。然而,过了一会儿(当我的小游戏结束时),我在 server 对象上调用 Dispose(),实现如下:
public void Dispose()
{
connection.Close(); // connection is the actual socket
commandBuff.Clear(); // this is just a StringBuilder
}
我在对象构造函数中也有这个:
public ConnectionWrapper()
{
commandBuff = new StringBuilder();
connection = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
connection.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
}
当我再次单击Listen 按钮时,我没有收到任何错误消息。客户端连接得很好,但是我的服务器端没有第二次检测到客户端连接,这基本上使服务器无论如何都无用。我猜它正在连接到旧的、挥之不去的套接字,但老实说,我不知道为什么会发生这种情况。这是客户端连接代码:
private void Connect_Click(object sender, EventArgs e)
{
try
{
client = new ConnectionWrapper();
HideControls();
alreadyReset = false;
IPAddress ip = IPAddress.Parse(IPEdit.Text);
int port = int.Parse(PortConnEdit.Text);
IPEndPoint ipe = new IPEndPoint(ip, port);
client.connection.BeginConnect(ipe, new AsyncCallback(OnConnectedToServer), null);
}
catch (Exception ex)
{
DispatchError(ex);
}
}
如果我在 CMD 中执行netstat -a,我看到我使用的端口仍然是绑定的,并且它的状态是LISTENING,即使在调用Dispose() 之后也是如此。我读到这是正常的,并且该端口“未绑定”存在超时。
有没有办法强制该端口解除绑定或设置一个非常短的超时时间,直到它自动解除绑定?现在,只有当我退出程序时它才会解除绑定。也许我在我的服务器上做错了什么?如果是这样,那会是什么?为什么客户端可以正常连接,但是服务端检测不到第二次?
我可以让套接字始终监听,而不是释放它,并使用单独的套接字来处理服务器连接,这可能会修复它,但我希望其他程序能够在连续播放会话之间使用该端口。
我记得看到另一个问题问这个问题,但我的情况没有令人满意的答案。
【问题讨论】:
-
当您运行
netstat时,您是否看到它处于TIME_WAIT状态? -
@Aaronaught:不,上面写着
LISTENING
标签: c# .net sockets asynchronous