Loading...
墨滴

jasonj333

2021/04/07  阅读:39  主题:红绯

端口

两台电脑可以根据双方的IP地址实现消息的发送与接收,电脑接收的数据会临时性的存放在接收缓冲区Recv-Q,等待应用程序来取走。然而,电脑系统的应用app有很多,如何通知正确的app取走数据?这就是传输层端口的作用

系统进程

如果你经常使用电脑,尤其是windows系统,肯定遇到过某个应用程序卡死的情况,这时候懂的都懂,默默地打开任务管理器,找到卡死的进程,右击结束进程,就可以强制关闭应用,读到这里你可能明白了:应用程序即进程

系统进程

Process,进程是指在系统中正在运行的一个应用程序,系统为每个进程分配唯一的进程号PID(Process ID),进程号PID就是应用程序的身份ID

试想一下,如果主机接收到的报文里携带某个应用程序的PID,不就可以通过这个PID通知相应的app来取走它的数据了嘛!可是找遍报文的所有字段,并没有进程号。那么操作系统如何将报文转交给真正的接收进程呢?

端口号

既然报文并不使用进程号来表示进程,那总归需要用某个东西和进程号绑定,曲线救国,实现把报文交给真正的进程吧,聪明的设计者想到了在传输层引入端口的概念

端口

传输层首部里的字段,分为源端口号和目的端口号,用来表示源主机的源应用程序和目的主机的目的应用程序

当应用程序想要和其他应用通信时,首先必须调用Bind(address, port)函数,将自己的进程号与本机的IP地址、端口号绑定起来 假设有一个进程A,它的进程号是4088,它这时候想要通信,首先创建一个socket套接字(TCP或UDP),然后用这个socket调用Bind('1.1.1.1',50001),操作系统就会把信息记录下来

(1.1.1.1,50001)----------------------- 4088

如果此时主机接收到一条报文,通过解封装网络层首部提取目的IP是1.1.1.1,解封装传输层首部提取目的端口号是50001,这两者的组合正好是(1.1.1.1,50001),操作系统根据它,正好查到这是发给进程号4088的进程的,然后就通知该进程A来取走数据

如果此时还有一个进程B,它也需要通信,创建完socket后,也Bind(1.1.1.1,50001),可以吗?这是不行的,(1.1.1.1,50001)在操作系统中只能被一个进程号绑定,这个组合是唯一的,不能同时被2个或两个以上的进程绑定。

怎么办?要么先解绑,就是关闭这个socket;或者调用socket的端口重用参数,让(1.1.1.1,50001)可以被另一个应用重用,但是之前的绑定将被新的绑定替代;要么换一个端口或者是ip地址,总之,(1.1.1.1,50001)这个组合不能同时和两个进程绑定

所以如果进程B可以Bind('1.1.1.1',60001),或者Bind('2.2.2.2',50001)。有的时候你可能并不想把ip地址写死,因为有可能代码需要在其他机器上运行,其他机器的ip地址并不是1.1.1.1或2.2.2.2,那怎么办?试试Bind('',60001),''表示任何IP地址,只要报文能够被主机接收,只要目的端口号是60001,不管它的IP地址是什么,都可以被绑定的进程接收。这让我想到之前TC8测试启动UpperTester时,只指定了端口号,并没有指定IP地址,就代表了任意IP地址都可以,增加了灵活性,而不是在主机的每个ip下都创建一个udpSocket

如果A Bind(1.1.1.1,50001),B是否可以Bind('',50001),答案也是:不可以!B的ip地址可以是任何ip,也包括了1.1.1.1,('',50001)这个集合也包括了(1.1.1.1,50001)

所以,进程监听的(address,port),address可以是确定的某个ip地址,也可以是任意的ip地址,如果是任意的ip地址,其他的应用就不能用这个port了


jasonj333

2021/04/07  阅读:39  主题:红绯

作者介绍

jasonj333