系统调用与网络通信过程
1. 网络连接建立前都会通过 socket系统调用,建立一个新的FD,只说明了类型。
socket() 系统调用创建一个套接字。
int socket(int domain, int type, int protocol); 返回的是int 表示 文件描述符号
这个套接字通常是(domain)指定为 AF_INET(IPv4)或 AF_INET6(IPv6),
并且(type)指定为 SOCK_STREAM(流套接字,如 TCP)或 SOCK_DGRAM(数据报套接字,如 UDP)。
(1)如果是属于ip地址,则可以分析a1,获取protocol 协议类型。
'udp': cls.UDP, 'tcp': cls.TCP, '02': cls.IPV4, '0A': cls.IPV6, '01': cls.UNIX_SOCKET, '10': cls.NETLINK_SOCKET
2. 客户端:
在 socket() 创建套接字之后,调用 connect() 建立与服务器的连接。使用connect(FD)
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
将套接字 sockfd 连接到指定的远程地址 addr,并指定地址结构体的长度 addrlen。
根据saddr解析的信息绑定FD。
(1)网络类型:生成networkidentifier(本地ip:port:None,None,远程ip:port【来自saddr】)
(2)unix域类型:生成unixidentifier
---- 绑定FD与描述符
但是客户端在系统调用层,缺失了本地的地址绑定。
使用 connect() 函数连接到远程服务器时,操作系统会分配一个本地端口号(通常是一个未使用的端口)并选择一个本地 IP 地址。这个自动分配的过程是由操作系统的网络栈实现的
主动获取本地地址方法: 连接建立成功后,可以使用 getsockname() 函数获取系统为套接字分配的本地 IP 地址和端口号
2. 服务端:
(1) 建立socket后,首先使用bind(FD)绑定本地地址(saddr)到FD。
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
将套接字 sockfd 绑定到指定的本地地址 addr,并指定地址结构体的长度 addrlen。
将saddr(unix域套接字地址,或本地ip地址),绑定到FD
(2)使用listen(FD)监听FD收到的请求request。
int listen(int sockfd, int backlog);
(3)使用accept(FD)系统调用,处理请求。
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
服务端会调用 accept() 系统调用来接受连接,并返回一个新的套接字,用于与该客户端进行通信。
--- 根据FD信息,与接收的客户端saddr地址建立连接。
(1)生成networkidentifier(本地ip:port【来自FD】,远程ip:port【来自saddr】)
(2)生成unixIdentifier 【根据FD绑定的本地unix域地址】
--- 生成newFD绑定描述符 networkidentifier 。
相关案例
对于客户端(例如你的计算机上运行的浏览器)在访问百度网站并获取图片时,每一步操作通常会涉及以下系统调用(假设使用常见的操作系统如Windows或类Unix系统):
- DNS解析:
- 客户端通过操作系统提供的系统调用(如 getaddrinfo())向本地DNS服务器发起DNS查询请求。在Windows中,可能会调用 getaddrinfo() 函数;在类Unix系统中,可能会调用 gethostbyname() 或 getaddrinfo() 函数。
- 建立TCP连接:
- 客户端通过操作系统提供的系统调用(如 socket()、connect())创建套接字(socket),并使用 connect() 函数发起与百度服务器的TCP连接。在Windows和类Unix系统中,这些函数都是标准的套接字API。
- 发送HTTP请求:
- 客户端通过操作系统提供的网络API(如 send())将HTTP GET请求发送到已建立的TCP连接。这个过程可能涉及多次 send() 调用,以确保完整的HTTP请求被发送到服务器。
- 接收HTTP响应:
- 当服务器响应到达时,客户端通过操作系统提供的网络API(如 recv())从TCP连接中接收HTTP响应。类似地,可能需要多次 recv() 调用来获取完整的响应数据。
- 显示图片:
- 客户端使用操作系统提供的图形用户界面(GUI)API来处理接收到的图片数据,并在浏览器窗口中显示。这些API涉及将图像数据解码并在屏幕上绘制出来。
- 关闭TCP连接:
- 当所有数据传输完成后,客户端通过调用 close() 或类似的函数关闭与百度服务器的TCP连接,释放相关的资源。在Windows和类Unix系统中,调用 closesocket() 或 close() 函数完成此操作
服务端:
- 服务端程序也会调用
socket()系统调用创建一个套接字,指定监听的地址族(通常是AF_INET或AF_INET6)和套接字类型(通常是SOCK_STREAM)。 - 创建套接字后,服务端程序会调用
bind()系统调用将套接字绑定到一个特定的本地地址和端口上。 - 然后服务端调用
listen()系统调用开始监听来自客户端的连接请求。 - 当有客户端连接请求到达时,服务端会调用
accept()系统调用来接受连接,并返回一个新的套接字,用于与该客户端进行通信。

浙公网安备 33010602011771号