【问题标题】:Timeout after 1024 connections from different virtual IPs来自不同虚拟 IP 的 1024 个连接后超时
【发布时间】:2015-05-18 09:01:28
【问题描述】:

我有一个问题,我一直在努力解决它。

我正在实现一个流量生成器,它有一个客户端和一个服务器端。客户端模拟具有唯一 IP 地址的设备。这些 IP 被添加为客户端上的虚拟接口,然后模拟设备绑定到该接口。然后,这些设备将连接到服务器端并产生往来于它的流量。

问题是我只能连接 1023 个设备,然后以下设备在连接时超时。我在服务器端签入了wireshark,我可以看到连接的SYN,但应用程序中从未收到它。当我重用 IP 以便使用少于 2014 年时,我可以建立任意数量的连接。

我创建了一个更容易运行的python程序,也有同样的问题:

client.py

import socket
import thread
import time
from subprocess import call

TCP_IP = '192.168.169.218'
TCP_PORT = 9999
BUFFER_SIZE = 1024
MESSAGE = "-" * 1000

if __name__=='__main__':
    sockets = []
    for i in range(0, 10020):
        ip = "13.1."+ str(((i/254)%254) + 1) + "." + str((i % 254) + 1)
        cmd = "ip addr add " + ip + " dev eth1;"
        call(cmd, shell=True)
        s = socket.create_connection((TCP_IP, TCP_PORT), 10, (ip, 0))
        sockets.append(s)

    while 1:
        for s in sockets:
            s.send(MESSAGE)
            data = s.recv(BUFFER_SIZE)

    for s in sockets:
        s.close()

server.py

from socket import *
import thread

BUFF = 1024
HOST = '192.168.169.218'
PORT = 9999

def handler(clientsock,addr):
    while 1:
        data = clientsock.recv(BUFF)
        if not data: break
        clientsock.send(data)
        # type 'close' on client console to close connection from the server side
        if "close" == data.rstrip(): break     
    clientsock.close()
    print addr, "- closed connection" #log on console

if __name__=='__main__':
    count = 0   
    ADDR = (HOST, PORT)
    serversock = socket(AF_INET, SOCK_STREAM)
    serversock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
    serversock.bind(ADDR)
    serversock.listen(5)
    while 1:
        print 'waiting for connection... listening on port', PORT
        clientsock, addr = serversock.accept()
        count += 1
        print count
        thread.start_new_thread(handler, (clientsock, addr))

我正在运行 CentOS 7.1 64 位,我测试的 Python 版本是 2.7.5。

到目前为止我做了什么:
- 将打开文件数限制(nofile)增加到 1040000
- 将 net.core.somaxconn 增加到 65535
- 将 net.ipv4.tcp_max_syn_backlog 和 net.core.netdev_max_backlog 增加到 30000
- 增加核心和 TCP 缓冲区
- 禁用防火墙并清除所有 iptables 规则

我测试了让 python 客户端在每次连接后休眠一秒钟,然后就没有问题了,所以我的猜测是有一些防洪保护或其他东西。有人有什么想法吗?

【问题讨论】:

标签: python linux sockets tcp network-programming


【解决方案1】:

有趣的问题,所以我用我的虚拟机做了一个测试。我能够发现,您正在达到 ARP 邻居条目的限制

# sysctl -a|grep net.ipv4.neigh.default.gc_thresh
net.ipv4.neigh.default.gc_thresh1 = 128
net.ipv4.neigh.default.gc_thresh2 = 512
net.ipv4.neigh.default.gc_thresh3 = 1024

以上是默认值,当您的第 1024 个连接填满此表时,垃圾收集器会再次开始运行 arp - 这会减慢并导致您的客户端超时

我可以将这些值设置如下

net.ipv4.neigh.default.gc_thresh1 = 16384
net.ipv4.neigh.default.gc_thresh2 = 32768
net.ipv4.neigh.default.gc_thresh3 = 65536

瞧!没有更多的 1024 限制 ..HTH

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-08
    • 2014-09-23
    • 1970-01-01
    • 2019-07-23
    • 1970-01-01
    • 2020-01-10
    • 1970-01-01
    相关资源
    最近更新 更多