【问题标题】:Is there any way to improve TCP connection time?有什么方法可以提高 TCP 连接时间?
【发布时间】:2012-05-07 22:24:32
【问题描述】:

我编写了一个 TCP 服务器来使用 BeginAccept/EndAccept 模式。有了这个,我使用 TcpClient 编写了一个简单的 UnitTest,并测量了每个部分。所有测试都是本地主机,所以我很惊讶地看到 TCP 连接始终需要 1 秒。我已经设置了Socket.NoDelay = true,尽管我相信这只会影响发送/接收。我没有收到第一个数据包。任何有关加快此过程的帮助或想法表示赞赏。

注意:我无法更改客户端以保持连接打开,并且如果可能,我需要能够每秒处理大量请求。

服务器端:

public void Start()
{
    System.Net.IPHostEntry localhost = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName());
    System.Net.IPEndPoint endpoint;
    int port = Properties.Settings.Default.ListenPort;

    //
    // Setup the connection to listen on the first IP, and specified port
    //
    endpoint = new IPEndPoint(IPAddress.Any, port);
    listenSocket = new Socket(endpoint.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
    listenSocket.Bind(endpoint);
    listenSocket.NoDelay = true; // do not wait 200 milliseconds for new data to be buffered on the connection
    listenSocket.Listen(int.MaxValue);
    Console.WriteLine("Listening on {0}:{1}", localhost.AddressList[0], port);

    //
    // Post the accept. The accept method will continuously post a new accept as soon as a connection is made
    //
    while (true)
    {
        accepted.Reset();
        Connection connection = connections.Pop();
        listenSocket.BeginAccept(AcceptCallback, connection);
        accepted.WaitOne();
    }
}

private static void AcceptCallback(IAsyncResult ar)
{
    accepted.Set();

    Connection connection = ar.AsyncState as Connection;
    Socket remoteSocket = null;

    try
    {
        remoteSocket = listenSocket.EndAccept(ar);
        remoteSocket.NoDelay = true;                
        connection.RemoteSocket = remoteSocket;

        //
        // Start the Receive cycle
        //
        Receive(connection);             
    }
    catch (SocketException)
    {
        Disconnect(connection);
    }           
}

简单测试客户端:

[TestMethod()]
public void ClientTest()
{
    TestContext.BeginTimer("Connection");
    TcpClient client = new TcpClient("localhost", 10300);
    NetworkStream stream = client.GetStream();
    TestContext.EndTimer("Connection");
    ...

使用 LoadTest 我加载了 25 个用户,而“连接”事务总是需要 1 秒以上。

【问题讨论】:

  • 尝试使用 Wireshark 嗅探 TCP 数据包,看看发生了什么。
  • @esac:可能是,这是主机名解析问题。是的,我看到主机名是“localhost”。但是您可以尝试通过 IP 地址建立连接吗?
  • 您是否正确释放连接?您使用哪个操作系统作为服务器?如果您运行的是 Windows 的非服务器版本,您可能会因连接限制而变慢。请参阅此thread 了解更多信息。

标签: c# sockets tcp connection performance-testing


【解决方案1】:

不知道为什么,只是简单地改变一下:

TestContext.BeginTimer("Connection");          
TcpClient client = new TcpClient("localhost", 10300);            
TestContext.EndTimer("Connection");

到这里:

TestContext.BeginTimer("Connection");
TcpClient client = new TcpClient();
client.Connect("localhost", 10300);       
TestContext.EndTimer("Connection");

将时间从 1 秒减少到 0.13 秒。将不得不调查原因,但希望这会在未来帮助某人。

【讨论】:

  • 很抱歉唤醒了一个老问题,但我很好奇你是否对此有过解释?这是实际修复还是有其他原因导致延迟?
  • @jishi 请参阅下面的 la-comadreja 评论 - 它解释得很好。
【解决方案2】:

当您尝试在解析为 Ipv6 和 Ipv4 地址的主机上使用 TcpClient 构造函数进行连接时,首先尝试使用 Ipv6 进行连接。如果失败,则尝试使用 IPv6 地址进行连接。这是 1 秒延迟的原因。 Here is the MSDN link:

【讨论】:

  • 你重复了Ipv6,那么哪个真正先出现?
  • 这个回答对我有帮助。我认为这种情况从服务器端更容易理解:我将服务器绑定到 IPv4 环回,但随后尝试通过域名“localhost”连接到客户端,该客户端解析为 IPv6 和 IPv4 地址。客户端首先尝试了 IPv6 地址,但由于服务器没有监听而失败。它默认为有效的 IPv4 地址,但速度很慢。我改为听 IPv6 环回,它再次运行得很快。
猜你喜欢
  • 1970-01-01
  • 2016-02-09
  • 1970-01-01
  • 1970-01-01
  • 2012-09-13
  • 1970-01-01
  • 2019-08-29
  • 2011-05-02
  • 2020-11-18
相关资源
最近更新 更多