日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

实例说明listen()函数第二个参数的意义与用法

發布時間:2025/3/21 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 实例说明listen()函数第二个参数的意义与用法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

我們先來看結果:

Client:

[cpp] view plain copy
  • #include?<sys/socket.h>??
  • #include?<stdio.h>??
  • #include?<string.h>??
  • #include?<netinet/in.h>??
  • #include?<stdlib.h>??
  • #include?<arpa/inet.h>??
  • ??
  • int?main(int?argc,char**?argv)??
  • {??
  • ????int?ret;??
  • ????int?sockfd?=?socket(AF_INET,SOCK_STREAM,0);??
  • ????if?(sockfd?==?-1)??
  • ????{??
  • ????????printf("socket?error\n");??
  • ????????return?-1;??
  • ????}??
  • ??
  • ????struct?sockaddr_in?serveraddr;??
  • ????memset(&serveraddr,0,sizeof(serveraddr));??
  • ????serveraddr.sin_family?=?AF_INET;??
  • ????inet_aton(argv[1],&serveraddr.sin_addr);??
  • ????serveraddr.sin_port?=?htons((unsigned?short)(atoi(argv[2])));??
  • ??????
  • ????ret?=?connect(sockfd,(const?sockaddr*)&serveraddr,sizeof(serveraddr));??
  • ????if?(ret?==?-1)??
  • ????{??
  • ????????printf("connect?error,ret?=?%d\n",ret);??
  • ????????return?-1;??
  • ????}??
  • ????
  • ????for(;;)??
  • ????{}??
  • ????return?0;??
  • }??

  • Server: [cpp] view plain copy
  • #include?<sys/socket.h>??
  • #include?<stdio.h>??
  • #include?<string.h>??
  • #include?<netinet/in.h>??
  • #include?<stdlib.h>??
  • #include?<arpa/inet.h>??
  • ??
  • ??
  • int?main(int?argc,char**?argv)??
  • {??
  • ????int?ret;??
  • ????int?listenfd?=?socket(AF_INET,SOCK_STREAM,0);??
  • ????if?(listenfd?==?-1)??
  • ????{??
  • ????????printf("socket?error\n");??
  • ????????return?-1;??
  • ????}??
  • ??
  • ????struct?sockaddr_in?serveraddr;??
  • ????memset(&serveraddr,0,sizeof(serveraddr));??
  • ????serveraddr.sin_family?=?AF_INET;??
  • ????serveraddr.sin_addr.s_addr?=?htonl(INADDR_ANY);??
  • ????serveraddr.sin_port?=?htons((unsigned?short)(atoi(argv[1])));??
  • ??
  • ????ret?=?bind(listenfd,(const?sockaddr*)&serveraddr,sizeof(serveraddr));??
  • ????if?(ret?==?-1)??
  • ????{??
  • ????????printf("bind?error,ret?=?%d\n",ret);??
  • ????????return?-1;??
  • ????}??
  • ??
  • ??<span?style="WHITE-SPACE:?pre">?</span>int?backlog?=?atoi(argv[2]);??
  • ????ret?=?listen(listenfd,?backlog);??
  • ????printf("backlog?=?%d,ret?=%d\n",backlog,ret);??
  • ????if?(ret?==?-1)??
  • ????{??
  • ????????printf("listen?error,ret?=?%d\n",ret);??
  • ????????return?-1;??
  • ????}??
  • ??????
  • ????for(;;)??
  • ????{}??
  • ????return?0;??
  • }??
  • server的代碼中通過命令行的方式傳入backlog的值,以便于我們通過修改backlog來觀察不同的backlog對程序的影響.

    開啟一個server與3個client.

    backlog = 1時:



    backlog = 2時:

    觀察上圖,server在19890端口監聽,3個client發起TCP連接。在第一幅圖中,對client而言,3個狀態均為established.對server而言,2個連接狀態為established,一個為syn_recv.第二幅圖中,對server而言,3個鏈接的狀態均為established。

    我們先來看一下TCP連接的狀態轉換



    再說回listen(int fd,int backlog)函數,內核會為一個監聽套接字維護兩個隊列,當有TCP請求到來時,即3次握手中的syn分節發送來時,會在未完成隊列中增加一項,3次握手完成時,未完成隊列中的項就移動到已完成隊列里,accept()函數會從已連接隊列里取走已完成連接.

    這個backlog參數就是控制我們的已連接隊列里等待accept()取走的連接的最大數目的.注意一點,backlog與這個已排隊連接的最大數目未必是完全相等的,不同的系統的實現可能不同.比如backlog=1,系統允許的實際一排隊數目可能為2.


    所以在上圖中,對client而言,connect()返回,TCP的狀態就轉變為established。而對server而言,3次握手完成TCP狀態才會轉換為established。在圖一中,由于backlog參數的限制,導致有一條連接并未完成3次握手,所以狀態為syn_recv。

    總結

    以上是生活随笔為你收集整理的实例说明listen()函数第二个参数的意义与用法的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。