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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux C++ 回射服务器

發布時間:2023/11/30 linux 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux C++ 回射服务器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

http://blog.csdn.net/qq_25425023/article/details/53914820

回射服務器就是服務端將客戶端的數據發送回去。

??

? 我實現的回射服務器返回增加了時間。


? 服務端代碼,可以很容易看懂:

?

[cpp]?view plain?copy
  • #include?<sys/socket.h>??
  • #include?<stdio.h>??
  • #include?<string.h>??
  • #include?<sys/types.h>??
  • #include?<netinet/in.h>??
  • #include?<time.h>??
  • #include?<unistd.h>??
  • #include?<arpa/inet.h>??
  • #include?<stdlib.h>??
  • ??
  • #include?"../thread_pool.h"??//在上一篇博客中??
  • ??
  • #define?MAX_BUFFER?512??
  • ??
  • typedef?struct?sockaddr?SSA;??
  • ??
  • char?timebuffer[50];??//存儲時間??
  • char?readbuffer[MAX_BUFFER];???//存儲客戶端數據??
  • time_t?tick;??
  • //任務類??
  • class?task??
  • {??
  • private:??
  • ????int?connfd;??//與客戶端連接的文件描述符??
  • public:??
  • ????task(int?conn)?:?connfd(conn)??
  • ????{??
  • ????}??
  • ????~task(){}??
  • ??
  • ????void?doit()??//線程池調用函數??
  • ????{??
  • ????size_t?readsize;??
  • ????while((readsize?=?read(connfd,?readbuffer,?MAX_BUFFER))?>?0)??//讀取客戶端數據??
  • ????{??
  • ????????printf("%ld?get?%dbyte\n",(unsigned?long)pthread_self()??
  • ?????????,?(int)readsize);???//測試用??
  • ????????if(readsize?==?-1)??//read出錯??
  • ????????{??
  • ????????printf("errno?is?%s\n",?strerror(errno));?//這里輸出"onnection?reset?by?peer"??
  • ????????continue;??
  • ????????}??
  • ????????readbuffer[readsize]?=?'\0';???
  • ????????tick?=?time(NULL);?//獲取時間??
  • ????????????snprintf(timebuffer,?sizeof(timebuffer),?"time?:?%.24s\r\n",???
  • ????????ctime(&tick));??
  • ????????strcat(readbuffer,?timebuffer);??//時間與客戶數據連接到一起??
  • ??????????
  • ????????write(connfd,?readbuffer,?strlen(readbuffer));??//發送給客戶端??
  • ????}??
  • //??printf("close?the?connfd\n");??
  • //??fflush(stdout);??
  • ??
  • ????close(connfd);??
  • ????}??
  • };??
  • ??
  • int?main(int?argc,?char?*argv[])??
  • {??
  • ????if(argc?!=?2)??
  • ????{??
  • ????printf("uasge?:?%s?port",?argv[0]);??
  • ????exit(-1);??
  • ????}??
  • ????int?sockfd,?connfd;??
  • ????struct?sockaddr_in?serv_addr,?cli_addr;??
  • ????int?port?=?atoi(argv[1]);??
  • ????//初始化sockaddr_in??
  • ????serv_addr.sin_family?=?AF_INET;??
  • ????serv_addr.sin_port?=?htons(port);??
  • ????serv_addr.sin_addr.s_addr?=?htonl(INADDR_ANY);??//允許任何人連接??
  • ????//創建套接字??
  • ????sockfd?=?socket(AF_INET,?SOCK_STREAM,?0);??
  • ????if(sockfd?<?0)??
  • ????{??
  • ????printf("socket?error'?n");??
  • ????exit(-1);??
  • ????}??
  • ????//綁定??
  • ????bind(sockfd,?(SSA?*)&serv_addr,?sizeof(serv_addr));??
  • ????//監聽套接字??
  • ????listen(sockfd,?6);??
  • ????//創建線程池??
  • ????threadpool<task>?pool(60,?100);??
  • ????pool.start();??//開啟線程池??
  • ????while(1)??
  • ????{??
  • ????socklen_t?len?=?sizeof(cli_addr);??
  • ????connfd?=?accept(sockfd,?(SSA?*)&cli_addr,?&len);??//接受連接??
  • ????task?*ta?=?new?task(connfd);???//新建任務??
  • ????char?buf[20];??
  • ????printf("IP?%s?conn\n",?inet_ntop(AF_INET,?&cli_addr.sin_addr,?buf,???
  • ????????sizeof(buf)));??
  • ????????while(!pool.append_task(ta))??//添加任務到任務隊列??
  • ????????printf("loop\n");?//測試用??
  • ????}??
  • ????return?0;??
  • }??

  • 下面的是客戶端的代碼:

    [cpp]?view plain?copy
  • #include?<stdio.h>??
  • #include?<sys/socket.h>??
  • #include?<arpa/inet.h>??
  • #include?<string.h>??
  • #include?<sys/types.h>??
  • #include?<unistd.h>??
  • #include?<netinet/in.h>??
  • #include?<stdlib.h>??
  • ??
  • int?main(int?argc,?char?*argv[])??
  • {??
  • ????if(argc?!=?3)?//參數不對,退出??
  • ????{??
  • ????printf("usage:?%s?ip?port\n",?argv[0]);??
  • ????exit(-1);??
  • ????}??
  • ????int?sockfd;??
  • ????struct?sockaddr_in?serv_addr;??
  • ????int?port?=?atoi(argv[2]);??//將字符串的端口轉換稱int??
  • ????//初始化服務端的端口和IP地址??
  • ????serv_addr.sin_family?=?AF_INET;??
  • ????serv_addr.sin_port?=?htons(port);??//將主機字節序轉換稱網絡字節序??
  • ????inet_pton(AF_INET,?argv[1],?&serv_addr.sin_addr);??
  • ????//創建套接字??
  • ????sockfd?=?socket(AF_INET,?SOCK_STREAM,?0);??
  • ????//連接??
  • ????connect(sockfd,?(struct?sockaddr?*)&serv_addr,???
  • ????????sizeof(serv_addr));??
  • ????char?buffer[50];??
  • ????write(sockfd,?"hello\n",?6);??//寫數據??
  • ????shutdown(sockfd,?SHUT_WR);??//解釋在下面??
  • ????size_t?num?=?read(sockfd,?buffer,?sizeof(buffer));??//讀數據??
  • ????buffer[num]?=?'\0';??
  • ????printf("read:?%s\n",?buffer);??
  • ????shutdown(sockfd,?SHUT_RD);??
  • //????close(sockfd);??
  • ????return?0;??
  • }??

  • 客戶端一開始我使用的是最后來個close的,就是注釋那部分,但是多個連接同時來的時候,服務端會出錯,具體的出錯信息是:Connection reset by peer,重新執行read之后,得到Hello的個數沒有少,也就是客戶端發送的個數。

    然而我客戶端寫完數據,就關閉寫端,讀取完數據,再關閉讀端,就不會出現這樣的錯誤。

    具體原因還不是很清楚,網上沒有查找到具體的答案。求大神來解答!!~~

    ==============================================

    終于知道原因了,出錯的是在服務端的read函數,read返回-1,而在客戶端,發送完數據,就shutdown寫端,發送完數據,就會發送FIN包,服務端read返回0,因為read不止被調用一次,第一次讀取完數據之后,繼續讀取,可是客戶端沒有數據可讀,就會出錯,而提前關閉客戶端寫端,所以read那里的WHILE退出,就沒有了出錯的信息。


    同時寫了兩個shell文件來測試:

    [html]?view plain?copy
  • #!/bin/bash??
  • ??
  • for?i?in?`seq?2000`???
  • do??
  • ????./client.out?127.0.0.1?8989??
  • done??

  • 循環 執行2000次。

    第二個shell文件:

    [html]?view plain?copy
  • #!/bin/bash??
  • ??
  • ./loop.sh?>?file1?&??
  • ./loop.sh?>?file2?&??
  • ./loop.sh?>?file3?&??
  • ./loop.sh?>?file4?&??
  • ./loop.sh?>?file5?&??
  • wait??
  • 開啟5個進程來返問。

    執行第二個shell文件

    最終,耗時為:

    [html]?view plain?copy
  • real????0m7.589s??
  • user????0m0.460s??
  • sys?0m1.944s??

  • 而且五個File文件中,有Hello的行數數都為2000.


    下一篇是實現一個簡單小型的web服務器。

    總結

    以上是生活随笔為你收集整理的Linux C++ 回射服务器的全部內容,希望文章能夠幫你解決所遇到的問題。

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