天天看點

C語言網絡程式設計:listen函數詳解

文章目錄

  • ​​前言​​
  • ​​函數描述​​
  • ​​代碼執行個體​​
  • ​​TCP伺服器為什麼調用listen​​
前言

根據TCP程式設計模型中我們可以看到之前的​

​socket​

​​和​

​bind​

​​接口是tcp伺服器在為接收用戶端的連結做準備,保證tcp的面向位元組流,面向連接配接的可靠通信服務正常進行。接下來的​

​listen​

​端口則為我們進行三次握手與用戶端進行連結的接口。

TCP程式設計模型如下

函數描述
  • ​#include <sys/socket.h>​

  • ​int listen(int sockfd, int backlog);​

  • 函數功能:将套接字檔案描述符從主動轉為被動檔案描述符,然後用于被動監聽用戶端的連接配接
  • 函數傳回值:成功傳回0,失敗傳回-1, errno被設定
  • 參數:

    a. ​​

    ​sockfd​

    ​​ 表示socket建立的套接字檔案描述符

    b. ​​

    ​backlog​

    ​​ 指定隊列的容量

    這個隊列用于記錄正在連接配接但是還沒有連接配接完成的用戶端,一般設定隊列的容量為2,3即可。隊列的最大容量需要小于30

代碼執行個體
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <errno.h>

void print_err(char *str, int line, int err_no) {
  printf("%d, %s :%s\n",line,str,strerror(err_no));
  _exit(-1);
}

int main()
{
  int skfd = -1, ret = -1;
  skfd = socket(AF_INET, SOCK_STREAM, 0);
  if ( -1 == skfd) {
    print_err("socket failed",__LINE__,errno);
  }

  struct sockaddr_in addr;
  addr.sin_family = AF_INET; //設定tcp協定族
  addr.sin_port = 6789; //設定端口号
  addr.sin_addr.s_addr = inet_addr("192.168.102.169"); //設定ip位址

  ret = bind(skfd, (struct sockaddr*)&addr, sizeof(addr));
  if ( -1 == ret) {
    print_err("bind failed",__LINE__,errno);
  }
  
  /*将套接字檔案描述符從主動轉為被動檔案描述符,然後用于被動監聽用戶端的連接配接*/
  ret = listen(skfd, 3);
  if ( -1 == ret ) {
    print_err("listen failed", __LINE__, errno);
  }
  
  return 0;
}      
TCP伺服器為什麼調用listen