我正在用C#编写一个TCP服务器,并且已经遇到了一个奇怪的和潜在的安全问题。Telnet阻止C#TCP服务器
我的用于接受新连接基本拱形如下:
- A C#插座端口上监听,使用
AcceptAsync
方法以接受传入的连接。 - 使用
ThreadPool
旋转接受的连接来完成接受。
一切正常,但是如果有人telnet进入端口,一切都会停止。
症状:
如果我远程登录到我的服务器和不发送任何数据(即不打任何键),服务器永远不会完成接受连接。
我的
SocketAsyncEventArgs.Completed
回拨永远不会被telnet连接命中。更糟的是,所有进一步的连接都被阻止/排队,并且从未被我的代码接受。他们被放进一个
CLOSE_WAIT
状态:TCP 127.0.0.1:8221 chance:53960 CLOSE_WAIT
TCP 127.0.0.1:8221 chance:53962 CLOSE_WAIT
TCP 127.0.0.1:8221 chance:53964 CLOSE_WAIT
任何意见,将不胜感激。
StartAccept:
private void StartAccept(SocketAsyncEventArgs AcceptArgs)
{
CurrentAcceptArgs = AcceptArgs;
AcceptArgs.AcceptSocket = null;
if (AcceptArgs.Buffer == null ||
AcceptArgs.Buffer.Length < 1024)
{
AcceptArgs.SetBuffer(new byte[1024], 0, 1024);
}
if (MainSocket != null)
{
lock (MainSocket)
{
// If this is false, we have an accept waiting right now, otherwise it will complete aynsc
if (MainSocket.AcceptAsync(AcceptArgs) == false)
{
ThreadPool.QueueUserWorkItem(FinishAccept, AcceptArgs);
StartAccept(GetConnection());
}
}
}
}
完成回叫,用于接受连接:
protected override void OnIOCompleted(object sender, SocketAsyncEventArgs e)
{
PWClientRemote RemoteClient = e.UserToken as PWClientRemote;
// Determine which type of operation just completed and call the associated handler.
switch (e.LastOperation)
{
case SocketAsyncOperation.Accept:
StartAccept(GetConnection());
ThreadPool.QueueUserWorkItem(FinishAccept, e);
break;
default:
base.OnIOCompleted(sender, e);
break;
}
}
完成接受:
private void FinishAccept(object StateObject)
{
SocketAsyncEventArgs args = (SocketAsyncEventArgs)StateObject;
FinishAcceptInternal(args);
}
下面是从连接的telnet但是在发送数据之前的Wireshark:
No. Time Source Destination Protocol Length Info
1 0.000000 192.168.1.146 192.168.1.109 TCP 66 59766 > 8221 [SYN] Seq=0 Win=8192 Len=0 MSS=1460 WS=256 SACK_PERM=1
2 0.000076 192.168.1.109 192.168.1.146 TCP 66 8221 > 59766 [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=1460 WS=256 SACK_PERM=1
3 0.000389 192.168.1.146 192.168.1.109 TCP 60 59766 > 8221 [ACK] Seq=1 Ack=1 Win=65536 Len=0
这应该是建立我的连接的完整握手,但不会引发Completed
事件。
您是否在CLOSE_WAIT上搜索过?如果你有,你知道你为什么得到它。代码在哪里? – jgauffin 2012-01-16 22:36:25
您可以指定连接尝试的超时时间吗? – Fantius 2012-01-17 00:02:51
是的,我知道我的连接停留在一个错误的TCP状态。我正在寻找解决方案。目前,恶意用户可能通过简单地使用telnet连接到服务器来挂起我的服务器。 – Stryck 2012-01-17 00:10:14