socket和accept返回的套接字(fd)有什麼區別

記錄unix網絡編程的複習之路

簡單回顧下socket鏈接過程


  • socket() --獲得fd!編程

    功能:指定了協議族(IPv四、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() --有人給我打電話嗎?socket

    功能:將未鏈接主動套接口的轉換爲被動套接口,指示內核接受對該套接口的鏈接請求。
     定義: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產生的套接字只是用來監聽的,不能直接用於發送接收數據。
相關文章
相關標籤/搜索