socket和accept返回的套接字fd有什么区别

8次阅读

共计 1214 个字符,预计需要花费 4 分钟才能阅读完成。

记录 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 产生的套接字只是用来监听的,不能直接用于发送接收数据。

正文完
 0