记录unix网络编程的复习之路
简单回顾下socket连接过程
-
socket() --得到fd!
功能:指定了协议族(IPv4、IPv6或unix)和套接口类型(字节流、数据报或原始套接口)。但并没有指定本地协议地址或远程协议地址。 定义:int socket(int family, int type, int protocol); 返回:出错:-1 成功:套接口描述字 (socket file descriptor)(套接字)sockfd
-
bind() --我在哪个端口?
功能:给套接口分配一个本地协议地址。 定义:int bind(int sockfd, const struct sockaddr *my_addr, int addrlen);
-
connect() --Hello!
功能:建立与TCP服务器的连接 定义:int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
-
listen() --有人给我打电话吗?
功能:将未连接主动套接口的转换为被动套接口,指示内核接受对该套接口的连接请求。 定义:int listen(int sockfd, int backlog); 参数: - sockfd调用socket函数返回的文件描述符(套接字). - 未完成连接队列和已完成连接队列的上限. - 未完成连接队列 : 服务端还未完成三次握手全部过程的一个队列. - 已完成连接队列 : 服务端已经完成三次握手全部过程的一个队列, 等待accept函数从这个队列中返回下一个(返回其实是取出, 该套接字不在已完成队列中了)套接字.
-
accept() --"Thank you for calling port 3490."
功能:accept函数从listen的已完成连接队列中返回下一个已完成连接, 也就是对端的套接字, 一个新的套接字. 当已完成连接队列的下一个完成 连接是空, 那么accept函数将被阻塞. 定义:int accept(int sockfd, struct sockaddr *cliaddr, int* addrlen); 返回:调用成功时返回: 1. cliaddr: 客户进程的协议地址和地址大小 2. 新套接口描述字
- send() 和 recv() --Talk to me, baby!
- close() --滚开!
socket()和accept()返回的fd
举个栗子:
一个客户端和一个服务端连接,双方socket产生各自的c_sock_fd和s_sock_fd;
s_sock_fd进行bind和listen后,accept准备接受客户端的连接请求;c_sock_fd调用connect请求连接服务端;
服务端接到请求产生accept_fd,届时accept_fd和c_sock_fd两个套接字可以通讯,而s_sock_fd则可以关闭;
客户端关闭close(c_sock_fd)后,服务端关闭所有未关闭的fd,通讯彻底断开。
ps:服务端的socket产生的套接字只是用来监听的,不能直接用于发送接收数据。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。