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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

socket选项: SO_REUSEADDR, SO_RCVBUF, SO_SNDBUF

發布時間:2023/12/9 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 socket选项: SO_REUSEADDR, SO_RCVBUF, SO_SNDBUF 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

From:?http://blog.csdn.net/jasonliuvip/article/details/22591531

最近在看《linux高性能服務器編程》,在此做個日記,以激勵自己,同時分享于有需要的朋友。


1. 讀取和設置socket文件描述符屬性:

[cpp]?view plaincopy
  • #include?<sys/socket.h>??
  • ??
  • int?getsockopt(int?sockfd,?int?level,?int?option_name,?void?*option_value,?socklen_t?*restrict?option_len);??
  • ??
  • int?setsockopt(int?sockfd,?int?level,?int?option_name,?const?void?*option_value,?socklen_t?option_len);??
  • sockfd參數指定被操作的目標socket。?

    level參數指定要操作哪個協議的選項,即屬性,比如:IPv4, IPv6, TCP 和通用socket選項。

    option_name參數指定選項的名字。

    option_value參數指定選項的值。

    option_len參參數指定選項的長度。

    調用成功時返回0, 失敗時返回-1, 并設置errno。


    2. 對服務器而言,有部分socket選項只能在調用listen前設置才會有效。因為連接socket只能由accept調用返回,而accept從listen監聽隊列中接受的連接至少已經完成了TCP三次握手的前兩個步聚,listen監聽隊列的連接至少已進入SYN_RCVD狀態,這時服務器已經往被連接上發送TCP同步報文。


    3. SO_REUSeADDR選項:重用本地地址

    未設置此項前,若服務端開啟后,又關閉,此時sock處于TIME_WAIT狀態,與之綁定的socket地址不可重用,而導致再次開啟服務端失敗。

    經過setsockopt設置之后, 即使處于TIME_WAIT些狀態也可以立即被重用。

    [cpp]?view plaincopy
  • int?reuse?=?1;??
  • setsockopt(sock,?SOL_SOCKET,?SO_REUSEADDR,?&reuse,?sizof(reuse));??

  • 4. SO_RCVBUF 和 SO_SNDBUF :TCP接收緩沖區和發送緩沖區的大小

    當然,即使我們設置了這兩項的大小時, 系統都會自動將其加倍, 并且不得小于某個最小值。

    TCP接收緩沖區的最小值是 256 字節, 而發送緩沖區的最小值是 2048 字節。(不同系統可能會有差異)

    這么做的目的是確保一個TCP連接擁有足夠多的空閑緩沖區來處理擁塞。

    [java]?view plaincopy
  • setsockopt(sock,?SOL_SOCKET,?SO_SNDBUF,?&sendbuf,?sizeof(sendbuf));??
  • getsockopt(sock,?SOL_SOCKET,?SO_SNDBUF,?&sendbuf,?(socklen_t*)&len);??
  • ??
  • setsockopt(sock,?SOL_SOCKET,?SO_RCVBUF,?&recvbuf,?sizeof(recvbuf));??
  • getsockopt(sock,?SOL_SOCKET,?SO_RCVBUF,?&recvbuf,?(socklen_t*)&len);??



  • 5. 代碼

    [cpp]?view plaincopy
  • //服務端??
  • #include?<stdio.h>??
  • #include?<stdlib.h>??
  • #include?<unistd.h>??
  • #include?<string.h>??
  • #include?<errno.h>??
  • #include?<sys/socket.h>??
  • #include?<arpa/inet.h>??
  • #include?<assert.h>??
  • ??
  • #define?BUFFER_SIZE?1024??
  • ??
  • int?main(int?argc,?char?**argv)??
  • {??
  • ????if?(argc?<=?3)?{??
  • ????????printf("Usage:?%s?ip?port?revc_size\n",?basename(argv[0]));??
  • ????????return?1;??
  • ????}??
  • ??????
  • ????const?char?*ip?=?argv[1];??
  • ????int?port?=?atoi(argv[2]);??
  • ??????
  • ????struct?sockaddr_in?address;??
  • ????bzero(&address,?sizeof(address));??
  • ????address.sin_family?=?AF_INET;??
  • ????address.sin_port?=?htons(port);??
  • ????inet_pton(AF_INET,?ip,?&address.sin_addr);??
  • ??????
  • ????int?sock?=?socket(PF_INET,?SOCK_STREAM,?0);??
  • ????assert(sock?>=?0);??
  • ??
  • ????????//設置地址可重用??
  • ????int?reuse?=?1;??
  • ????setsockopt(sock,?SOL_SOCKET,?SO_REUSEADDR,?&reuse,?sizof(reuse));??
  • ??????
  • ????int?recvbuf?=?atoi(argv[3]);??
  • ????int?len?=?sizeof(recvbuf);??
  • ??????
  • ????????//設置接受緩沖區大小??
  • ????setsockopt(sock,?SOL_SOCKET,?SO_RCVBUF,?&recvbuf,?sizeof(recvbuf));??
  • ????????//獲取系統修改后的大小??
  • ????????getsockopt(sock,?SOL_SOCKET,?SO_RCVBUF,?&recvbuf,?(socklen_t*)&len);??
  • ????printf("the?receive?buffer?size?after?setting?is?%d\n",?recvbuf);??
  • ??????
  • ????int?ret?=?bind(sock,?(struct?sockaddr*)&address,?sizeof(address));??
  • ????assert(ret?!=?-1);??
  • ??????
  • ????ret?=?listen(sock,?5);??
  • ????assert(ret?!=?-1);??
  • ??????
  • ????struct?sockaddr_in?client;??
  • ????socklen_t?client_addrlength?=?sizeof(client);??
  • ??????
  • ????int?connfd?=?accept(sock,?(struct?sockaddr*)&client,?&client_addrlength);??
  • ????if?(connfd?<?0)?{??
  • ????????printf("errno?is:?%d\n",?errno);??
  • ????}??
  • ????else?{??
  • ????????char?buffer[BUFFER_SIZE];??
  • ????????memset(buffer,?'\0',?BUFFER_SIZE);??
  • ??????????
  • ????????while?(recv(connfd,?buffer,?BUFFER_SIZE-1,?0)?>?0);??
  • ??????????
  • ????????printf("recv:?%s\n",?buffer);??
  • ????????close(connfd);??
  • ????}??
  • ??????
  • ????close(sock);??
  • ??????
  • ????return?0;??
  • }??
  • 運行后:

    jason@lightning:~/myproject/test_recv$ ./test_recv localhost 8000 50
    the receive buffer size after setting is 2280

    很明顯被修改過了, 我們給的50, 被改為2280。



    [cpp]?view plaincopy
  • //客戶端??
  • #include?<stdio.h>??
  • #include?<sys/socket.h>??
  • #include?<arpa/inet.h>??
  • #include?<assert.h>??
  • #include?<unistd.h>??
  • #include?<stdlib.h>??
  • #include?<string.h>??
  • ??
  • #define?BUFFER_SIZE?1024??
  • ??
  • int?main(int?argc,?char?**argv)??
  • {??
  • ????if(argc?<=?3)?{??
  • ????????fprintf(stderr,?"Usage:?%s?ip?port?send_buffer_size\n",???
  • ????????????????basename(argv[0]));??
  • ????????return?1;??
  • ????}??
  • ??????
  • ????const?char?*ip?=?argv[1];??
  • ????int?port?=?atoi(argv[2]);??
  • ??????
  • ????struct?sockaddr_in?server_address;??
  • ????bzero(&server_address,?sizeof(server_address));??
  • ????server_address.sin_family?=?AF_INET;??
  • ????server_address.sin_port?=?htons(port);??
  • ????inet_pton(AF_INET,?ip,?&server_address.sin_addr);??
  • ??
  • ????int?sock?=?socket(PF_INET,?SOCK_STREAM,?0);??
  • ????assert(sock?>=?0);??
  • ??????
  • ????int?sendbuf?=?atoi(argv[3]);??
  • ????int?len?=?sizeof(sendbuf);??
  • ??????
  • ????????//設置發送緩沖區大小??
  • ????setsockopt(sock,?SOL_SOCKET,?SO_SNDBUF,?&sendbuf,?sizeof(sendbuf));??
  • ????????//獲取系統修改后的大小??
  • ????????getsockopt(sock,?SOL_SOCKET,?SO_SNDBUF,?&sendbuf,?(socklen_t*)&len);??
  • ??????
  • ????printf("the?tcp?send?buffer?size?after?setting?is?%d\n",??
  • ????????????sendbuf);??
  • ??????
  • ????if?(connect(sock,?(struct?sockaddr*)&server_address,?sizeof(server_address))?!=?-1)?{??
  • ????????char?buffer[BUFFER_SIZE];??
  • ????????memset(buffer,?'a',?BUFFER_SIZE);??
  • ????????send(sock,?buffer,?BUFFER_SIZE,?0);??
  • ????}??
  • ????else?{??
  • ????????printf("connect?%s?failed\n",?ip);??
  • ????}??
  • ??????
  • ????close(sock);??
  • ??????
  • ????return?0;??
  • }??

  • 運行后:

    jason@lightning:~/myproject/test_send$ ./test_send localhost 8000 2000
    the tcp send buffer size after setting is 4000

    給的是2000, 被改成4000了。


    總結

    以上是生活随笔為你收集整理的socket选项: SO_REUSEADDR, SO_RCVBUF, SO_SNDBUF的全部內容,希望文章能夠幫你解決所遇到的問題。

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