如何理解TCP端口

来源:互联网 发布:网络优化工程师好学不 编辑:程序博客网 时间:2024/06/16 15:12

如何理解TCP端口

问题:一台主机配置多张网卡,假设同时配置了2张网卡,这个时候这台主机有多少个TCP Port可用?

Port

这个问题让我重新思考TCP Port的作用,它是用来标识应用层的网络服务的!原来的理解认为,一台主机只会有65536个端口,并且是0-65535,每个都惟一的。并且在学socket编程的时候,有一个SO_Reuse_Addr的问题,更是坚定了Tcp Port惟一的想法。但是现在看来,事实并不是这样的。

现在个人计算机比较普及,并且99.99%的个人计算机只会同时连接一个网络,即使我们的Laptop同时拥有Eth0WLan0两张网卡,即大部分人的一台机器在一个时候只会用一个IP地址,所以我们平时在一个主机上都不会看到重复的端口号。

复用一张网卡

重新描述一下上面关于端口作用的表述:在复用单一网络地址时,TCP Port用于在应用层区分目的服务方。即我们在应用层复用了一张网卡,从这张网卡上收到的数据,可以传输给不同的服务程序,每个服务程序使用Port来区分。

如何我们有两张网卡,那么每张网卡各有同样的端口号。

##内核如何管理重复的Port
创建socket的接口:
int socket(int domain, int type, int protocol);
命名socket的接口:
int bind(int socket, const struct sockaddr *address, socklen_t address_len);
其中,一般来说不对address这个类型的参数做参数,一般用这个:

 `struct  sockaddr_in {    short  int  sin_family;                      /* Address family */    unsigned  short  int  sin_port;       /* Port number */    struct  in_addr  sin_addr;              /* Internet address */    unsigned  char  sin_zero[8];         /* Same size as struct sockaddr */};`

这个参数里机包括了:要监听的ip地址与tcp端口。

内核如何管理连接

事实上,内核基于iptcp port就可以区分端口,因为一个tcp链是一个五元组:
[src_ip, src_port, dst_ip, dst_port, tos]
对这个五元组做一下hash就可以很简单地管理了。
事实上,我们也同时回答了一个主机的一个端口最大可以接受多少client的连接这个问题:
理论上是不限制的,但是机制总是有限制的,我认为这边主要的限制在于内存。

验证

猜想:一个Linux主机可以同时监听不同ip地址的同一个端口。
这也是上面分析得出来的结论,也是网络设计上应该想要达到的目标。

验证:简单一点的方案就是,在一台主机上,对不同的网卡绑定不同的ip地址,运行两个服务去监听不同ip地址上的同一个端口。

具体方案:找现在可用的,Linux主机上事实已经有两张网卡了,一个是lo,一个是eth0。现有环境如下:
lo:地址127.0.0.1
eth0172.16.82.105

redis-server可以bind到不同的ip地址,刚好环境里面有,直接改配置文件,如下:

配置文件A:
bind 127.0.0.1 //listen on localhost
port 6379

配置文件B:
bind 172.16.82.105 //listen on eth0
port 6379

分别使用两个配置文件启动两个redis实例,效果如下:
这里写图片描述
两个实例均成功创建了,并且同时listen 6379这个端口,通过redis-cli连接,一切运行正常。

结论

一台主机理论上可以有无限多个端口,并且端口号可以重复。
这是我个人关于网络的端口理解上的一个重要一步,记录一下。

原创粉丝点击