博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
tcp的65535个连接之迷
阅读量:4319 次
发布时间:2019-06-06

本文共 3079 字,大约阅读时间需要 10 分钟。

前言

在的最后有提到一个问题,其实这是个既简单又复杂的问题。

机器连接数

记得以前一台机器只能建立65535个连接的这种想法一直长时间占据着思维方式,为什么会有这种想法呢,估计最早起源于学校的portshort1665535)吧。

一台机器connect同一IP,port的最大连接数

嗯,既然一台机器只能最大建立65535个连接,那当然 为什么一台机器connect同一个IPporttcp连接数不能超过65535这个问题的答案是对的,没有为什么。

真的是这样的么。 

TCP连接的唯一性

前面提到的所有的问题,其实都可以归结为一个问题,就是TCP连接的唯一性,是靠系统内部的什么来保证的。其实以前我已经说过,TCP连接在内部是由一个四元组来形成,即(src_ip,src_port,dst_ip,dst_port),当然其实是这4个值的简单的hash值来决定的。侯捷说,源码之前,了无私密。所以我们简单的如下看下去(采用linux内核2.6.16)

如下所示:

inet_hashtables.h

static inline struct sock *inet_lookup(struct inet_hashinfo *hashinfo,

                                       const u32 saddr, const u16 sport,

                                       const u32 daddr, const u16 dport,

                                       const int dif)

{

        struct sock *sk;

 

        local_bh_disable();

        sk = __inet_lookup(hashinfo, saddr, sport, daddr, ntohs(dport), dif);

        local_bh_enable();

 

        return sk;

}

static inline struct sock *__inet_lookup(struct inet_hashinfo *hashinfo,

                                         const u32 saddr, const u16 sport,

                                         const u32 daddr, const u16 hnum,

                                         const int dif)

{

        struct sock *sk = __inet_lookup_established(hashinfo, saddr, sport, daddr,

                                                    hnum, dif);

        return sk ? : inet_lookup_listener(hashinfo, daddr, hnum, dif);

}

static inline struct sock *

        __inet_lookup_established(struct inet_hashinfo *hashinfo,

                                  const u32 saddr, const u16 sport,

                                  const u32 daddr, const u16 hnum,

                                  const int dif)

{

        INET_ADDR_COOKIE(acookie, saddr, daddr)

        const __u32 ports = INET_COMBINED_PORTS(sport, hnum);

        struct sock *sk;

        const struct hlist_node *node;

        /* Optimize here for direct hit, only listening connections can

         * have wildcards anyways.

         */

        unsigned int hash = inet_ehashfn(daddr, hnum, saddr, sport);

        struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash);

 

        prefetch(head->chain.first);

        read_lock(&head->lock);

        sk_for_each(sk, node, &head->chain) {

                if (INET_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))

                        goto hit; /* You sunk my battleship! */

        }

 

        /* Must check for a TIME_WAIT'er before going to listener hash. */

        sk_for_each(sk, node, &(head + hashinfo->ehash_size)->chain) {

                if (INET_TW_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))

                        goto hit;

        }

        sk = NULL;

out:

        read_unlock(&head->lock);

        return sk;

hit:

        sock_hold(sk);

        goto out;

}

 

其中:socksocket的一个内部结构,从__inet_lookup_established的名字可以看出,这个是查找建立的socket连接的函数,好,我们继续看下去:

inet_sock.h

static inline unsigned int inet_ehashfn(const __u32 laddr, const __u16 lport,

                                        const __u32 faddr, const __u16 fport)

{

        unsigned int h = (laddr ^ lport) ^ (faddr ^ fport);

        h ^= h >> 16;

        h ^= h >> 8;

        return h;

}

 

static inline int inet_sk_ehashfn(const struct sock *sk)

{

        const struct inet_sock *inet = inet_sk(sk);

        const __u32 laddr = inet->rcv_saddr;

        const __u16 lport = inet->num;

        const __u32 faddr = inet->daddr;

        const __u16 fport = inet->dport;

 

        return inet_ehashfn(laddr, lport, faddr, fport);

}

从上面的代码里面明显可以看出,inet_ehashfn函数就是计算hash值的方法,也证明了socket其实是4元组组成的论据。

有了上面的源码,现在回到问题

问题一:机器的连接数

所以一台机器的TCP连接数是不只65535的,为什么,因为4元组的组合至少是无限的,机器的连接数,取决于机器的内存,机器的CPU等等这些因素。

问题二:一台机器connect同一IP,port的最大连接数

那为什么同一台机器连接同一ipport的最大连接数是63335呢,是因为在4元组(src_ip,src_port,dst_ip,dst_port)中,src_ip, dst_ip, dst_port是都是固定的,只有src_port可以变化,所以根据short,所以才是65535.

转载于:https://www.cnblogs.com/ouzi/archive/2012/10/29/2745430.html

你可能感兴趣的文章
hihocoder 1643 Puzzle Game(北京icpc2017 现场赛)
查看>>
vim 简单理解三种模式 粗暴入门
查看>>
django模板层之静态文件引入优化
查看>>
转载使用命令wsimport构建WebService客户端
查看>>
java实现23种设计模式之模版方法模式
查看>>
小程序·云开发实战 - 校园约拍小程序
查看>>
闲话函数式变成与OOP
查看>>
Linux-正则表达式与三剑客
查看>>
php中,post与get获取参数的异同
查看>>
警惕!年轻人要拥抱自动化和人工智能作为通信的未来
查看>>
Python给数字前固定位数加零
查看>>
python 多进程和多线程对比
查看>>
【转载】 wpf无边框的方法以及拖拽的问题
查看>>
Web自动化测试 二 ----- HTML
查看>>
sql 入门经典(第五版) Ryan Stephens 学习笔记  第四部分:建立复杂的数据库查询/...
查看>>
[原创]Keys的基本操作总结,判断Keys中是否存在Keys.Control|Keys.Alt,移除Keys中的部分键值。...
查看>>
主题样式之背景图片不随鼠标滑动而移动
查看>>
Centos 中文乱码
查看>>
IDLE常用快捷键
查看>>
MyBatis课程4
查看>>