当前位置:首页 > 单片机 > CPP开发者
[导读]在TCP连接中,客户端在发起连接请求前会先确定一个客户端端口,然后用这个端口去和服务器端进行握手建立连接。那么在Linux上,客户端的端口到底是如何被确定下来的呢?事实上很多我们平时遇到的问题都和这个端口选择过程相关,如果能深度理解这个过程,将有助于我们对这些问题的深刻理解。Ca...

TCP 连接中,客户端在发起连接请求前会先确定一个客户端端口,然后用这个端口去和服务器端进行握手建立连接。那么在 Linux 上,客户端的端口到底是如何被确定下来的呢?

事实上很多我们平时遇到的问题都和这个端口选择过程相关,如果能深度理解这个过程,将有助于我们对这些问题的深刻理解。

  • Cannot assign requested address 报错是怎么回事?
  • 一个客户端端口可以同时用在两条 TCP 连接上吗?
还是让我们借助一段简单到只有两句的代码,从这个来讲起!

int main(){
 fd = socket(AF_INET,SOCK_STREAM, 0);
 connect(fd, ...);
 ...
}

一、创建 socket

客户端在发起连接的时候,需要事先创建一个 socket。在 c 语言中,就是调用 socket 函数,例如 socket(AF_INET,SOCK_STREAM, 0) 这句。

socket 函数执行完毕后,在用户层视角我们是看到返回了一个文件描述符 fd。但在内核中其实是一套内核对象组合,大体结构如下。

从上图我们看到,socket 在内核里并不是一个内核对象。而是包含 file、socket、sock 等多个相关内核对象构成,每个内核对象还定义了 ops 操作函数集合。在后面的内核源码执行过程中,我们需要时不时回头来看这些内核对象,这里先简单了解一下就行。

这些内核对象都是在 socket 系统调用执行过程中创建出来的。为了避免喧宾夺主,这里只列出入口代码,详细过程就不展开介绍了。

//file: net/socket.c
SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)
{
 //创建 socket、sock 等内核对象,并初始化
 sock_create(family, type, protocol, 
本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
换一批
延伸阅读
关闭