远程登录阻止C#TCP服务器

编程入门 行业动态 更新时间:2024-10-21 15:55:45
本文介绍了远程登录阻止C#TCP服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我写在C#中的TCP服务器,并遇到了一个奇怪的和潜在的安全性问题,以及。

I am writing a TCP server in C#, and have run into a strange and potentially a security issue as well.

我接受新的连接基本牌坊如下:

My basic arch for accepting new connections is as follows:

  • AC#插座端口上监听,使用 AcceptAsync方法的方法来接受传入的连接。
  • 分拆使用线程池为完成接受。
  • A C# Socket listening on a port, using the AcceptAsync method to accept incoming connections.
  • Spinning off accepted connections using the ThreadPool for finishing the accept.
  • 一切都工作的很好,但是一切都研磨到,如果停止某人远程登录到该端口。

    Everything works quite well, however everything grinds to a halt if someone telnets into the port.

    症状:

    • 如果我远程登录到我的服务器,并做不发送任何数据(即不打任何键),服务器永远不会完成接受连接。

    • If I telnet into my server and do not send any data (i.e. do not hit any keys) the server will never finish accepting the connection.

    我的 SocketAsyncEventArgs.Completed 回调从不打的telnet连接。

    My SocketAsyncEventArgs.Completed callback is never hit for the telnet connection.

    更糟糕的是,所有进一步的连接被阻塞/排队,千万不要被我的代码接受。它们被放入 CLOSE_WAIT 状态:

    Even worse, all further connections are blocked/queued and never get accepted by my code. They are put into a CLOSE_WAIT state:

    TCP 127.0.0.1:8221机会: 53960 CLOSE_WAIT

    TCP 127.0.0.1:8221机会:53962 CLOSE_WAIT

    TCP 127.0.0.1:8221机会:53964 CLOSE_WAIT

    任何意见,将不胜感激。

    Any advice would be appreciated.

    StartAccept:

    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的,但发送数据之前:

    Here is the wireshark from connecting telnet but before sending data:

    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

    这应该是完整的握手建立我的连接,但已完成事件从未提出。

    This should be the complete handshake to establish my connection, but the Completed event is never raised.

    推荐答案

    回答我的问题,因为我找到了根本原因:

    Answering my own question, as I found the underlying cause:

    该错误是这一行:

    if (AcceptArgs.Buffer == null || AcceptArgs.Buffer.Length < 1024) { AcceptArgs.SetBuffer(new byte[1024], 0, 1024); }

    这是因为如果你设置一个缓冲区,AcceptAsync方法将阻塞,直到它收到一些数据。

    This is because if you set a buffer, AcceptAsync will block until it receives some data.

    从的 MSDN :

    所需的最小缓冲区大小为288字节。如果指定了较大的缓冲区大小,则套接字将预计比在Winsock的AcceptEx调用接收的地址数据的一些额外的数据等,并会等到收到此额外的数据。

    The minimum buffer size required is 288 bytes. If a larger buffer size is specified, then the Socket will expect some extra data other than the address data received by the Winsock AcceptEx call and will wait until this extra data is received.

    我纠正代码:

    // We set a null buffer here. // If we set a valid buffer, the accept will expect data // and will hang unless it gets it. AcceptArgs.SetBuffer(null, 0, 0);

    我不知道这是否是准确的正确的修复,设置288个字节或更小的缓冲区似乎没有解决问题。只有设置缓冲区为空造成不发送数据连接时要提出的已完成事件。

    更多推荐

    远程登录阻止C#TCP服务器

    本文发布于:2023-11-25 02:53:28,感谢您对本站的认可!
    本文链接:https://www.elefans.com/category/jswz/34/1628028.html
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:服务器   远程登录   TCP

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!