-- TOC --
这是个很有趣的问题,需要仔细研究。
A TCP/UDP connection is identified by a tuple of five values:
{<protocol>, <src addr>, <src port>, <dest addr>, <dest port>}
Any unique combination of these values identifies a connection. As a result, no two connections can have the same five values, otherwise the system would not be able to distinguish these connections any longer.
一个五元组定义一路连接。
The protocol of a socket is set when a socket is created with the socket()
function. The source address and port are set with the bind()
function. The destination address and port are set with the connect()
function. Since UDP is a connectionless protocol, UDP sockets can be used without connecting them. Yet it is allowed to connect them and in some cases very advantageous for your code and general application design. In connectionless mode, UDP sockets that were not explicitly bound when data is sent over them for the first time are usually automatically bound by the system, as an unbound UDP socket cannot receive any (reply) data. Same is true for an unbound TCP socket, it is automatically bound before it will be connected.
这段文字关于UDP的描述很重要,解开了长久以来的一些似似而非的困惑。UDP也可以调用bind和connect,可以不调用是因为底层有自动的机制。
我觉得以下的说法并不绝对,但方向正确:
启动线程数=[任务执行时间/(任务执行时间-IO等待时间)]* CPU内核数
最佳启动线程数和CPU内核数量成正比,和IO阻塞时间也成正比(阻塞时间越长,可启动线程数就越多)。如果任务都是CPU计算型任务(阻塞时间趋近于零),那么线程数最多不超过CPU内核数,因为启动再多线程,CPU也来不及调度;相反如果是任务需要等待磁盘操作,网络响应,那么多启动线程有助于提高任务并发度,提高系统吞吐能力,改善系统性能。
注意,这里的线程是真的线程,而不是像Python那样的“假线程”。
一定是线程吗?进程呢?或者多个进程,每个进程各自派生出一堆线程?哪种进程和线程模型最好呢?
TCP Server监听Client的连接,当有连接到来时,创建一个对应的socket,不过此socket的地址和端口,与监听端口一样,因此tcp服务器的socket不占用本地的端口资源。系统用一个4四元组来唯一标识一个TCP连接:{local ip, local port,remote ip,remote port}。TCP Server上的socket,local部分是一样的,只有remote部分不一样。理论连接数的上限非常高,但实际会受到各种资源的限制,比如内存资源和文件描述符资源(每个socket,都是一个fd)。
增加系统内存资源,修改Linux系统文件描述符支持上限,可以提高tcp并发连接数量,据说目前单台系统上万并发数量已经没啥难度了。(C10K文件,我理解是Concurrent 10K)
TCP连出受端口限制,连入仅受内存限制。
TCP Client可以修改内核参数net.ipv4.ip_local_port_range
,扩大可使用端口范围。
本文链接:https://cs.pynote.net/net/tcp/202205011/
-- EOF --
-- MORE --