1. 程式人生 > >【轉】TCP粘包問題解決方法之\n\r

【轉】TCP粘包問題解決方法之\n\r

該方案,每次讀取時當讀到‘\n’換行符時,讀取該行

伺服器端:

[cpp]  view plain  copy
  1. #include<unistd.h>  
  2. #include<sys/types.h>  
  3. #include<sys/socket.h>  
  4. #include<netinet/in.h>  
  5. #include<arpa/inet.h>  
  6. #include<stdlib.h>  
  7. #include<stdio.h>  
  8. #include<errno.h>  
  9. #include<string.h>  
  10. #define ERR_EXIT(m) do{perror(m);exit(EXIT_FAILURE);}while(1)  
  11. struct
     packet  
  12. {  
  13.     int len;  
  14.     char buf[1024];  
  15. };  
  16. ssize_t readn(int fd, void *buf, size_t count)  
  17. {  
  18.     size_t
     nleft = count;  
  19.     ssize_t nread;  
  20.     char *bufp = (char*)buf;  
  21.     while (nleft > 0)  
  22.     {  
  23.         if ((nread = read(fd, bufp, nleft)) < 0)  
  24.         {  
  25.             if (errno == EINTR)  
  26.             {  
  27.                 continue;  
  28.                 return -1;  
  29.             }  
  30.             else if (nread == 0)return count - nleft;  
  31.         }  
  32.         bufp = bufp + nread;  
  33.         nleft = nleft - nread;  
  34.     }  
  35.     return count;  
  36. }  
  37. ssize_t writen(int fd, void *buf, size_t count)  
  38. {  
  39.     size_t nleft = count;  
  40.     ssize_t nwrite;  
  41.     char *bufp = (char*)buf;  
  42.     while (nleft > 0)  
  43.     {  
  44.         if ((nwrite = write(fd, bufp, nleft)) < 0)  
  45.         {  
  46.             if (errno == EINTR)  
  47.             {  
  48.                 continue;  
  49.                 return -1;  
  50.             }  
  51.             else if (nwrite == 0)continue;  
  52.         }  
  53.         bufp = bufp + nwrite;  
  54.         nleft = nleft - nwrite;  
  55.     }  
  56.     return count;  
  57. }  
  58. ssize_t recv_peek(int sockfd, void *buf, size_t len)  
  59. {  
  60.     while (1)  
  61.     {  
  62.         int ret = recv(sockfd, buf, len, MSG_PEEK);  
  63.         if (ret == -1 && errno == EINTR)continue;  
  64.         return ret;  
  65.     }  
  66. }  
  67. ssize_t readline(int sockfd, void *buf, size_t maxline)  
  68. {  
  69.     int ret;  
  70.     int nread;  
  71.     char *bufp = (char*)buf;  
  72.     int nleft = maxline;  
  73.     while (1)  
  74.     {  
  75.         ret = recv_peek(sockfd, bufp, nleft);  
  76.         if (ret < 0)return ret;  
  77.         else if (ret == 0)return ret;//對方關閉了套介面  
  78.         nread = ret;  
  79.         for (int i = 0; i < nread; i++)  
  80.         {  
  81.             if (bufp[i] == '\n')  
  82.             {  
  83.                 ret = readn(sockfd, bufp, i + 1);//將緩衝區資料移除  
  84.                 if (ret != i + 1)exit(EXIT_FAILURE);  
  85.                 return ret;  
  86.             }  
  87.         }  
  88.         if (nread>nleft)exit(EXIT_FAILURE);//讀到的資料不能超過緩衝區  
  89.         nleft -= nread;  
  90.         ret = readn(sockfd, bufp, nread);  
  91.         if (ret != nread)exit(EXIT_FAILURE);  
  92.         bufp += nread;  
  93.     }  
  94.     return -1;  
  95. }  
  96. void do_service(int connfd)  
  97. {  
  98.     char recvbuf[1024];  
  99.     int n;  
  100.     while (1)  
  101.     {  
  102.         memset(&recvbuf, 0, sizeof(recvbuf));  
  103.         int ret = readline(connfd, recvbuf, 1204);  
  104.         if (ret == -1)  
  105.         {  
  106.             ERR_EXIT("read");  
  107.         }  
  108.         else if (ret ==0 )  
  109.         {  
  110.             printf("client cloase\n");  
  111.             break;  
  112.         }  
  113.         fputs(recvbuf, stdout);  
  114.         writen(connfd, recvbuf, strlen(recvbuf));  
  115.     }  
  116. }  
  117. 相關推薦

    TCP問題解決方法\n\r

    該方案,每次讀取時當讀到‘\n’換行符時,讀取該行 伺服器端: [cpp]  view plain  copy #include<uni

    轉載TCP問題分析和解決(全)

    刪除 而且 實例 報文 底層 nagle 存在 ngxin 想想 TCP通信粘包問題分析和解決(全) 在socket網絡程序中,TCP和UDP分別是面向連接和非面向連接的。因此TCP的socket編程,收發兩端(客戶端和服務器端)都要有成對的socket,因此,發送端為了將

    Git衝突與解決方法 Git衝突與解決方法

    本文轉載自:https://www.cnblogs.com/gavincoder/p/9071959.html Git衝突與解決方法 1、git衝突的場景 情景一:多個分支程式碼合併到一個分支時; 情景二:多個分支向同一個遠端分支推送程式碼時; 實際上,push操作即是將

    海量數據解決思路BitMap

    處理 blank cpp 標識 targe 方案 排序。 十進制數 一次 轉載(http://zengzhaozheng.blog.51cto.com/8219051/1404108) 一、概述 本文將講述Bit-Map算法的相關原理,Bit-Map算法的一些利用場景,

    socket tcp 解決

    connect line 應該 字節 unpack otto stdout except soc 何為粘包: 先看代碼 session=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 在定義socket對象的時候 有兩個參數

    安裝Vue.js的方法

    環境搭建 node.js 初始化 其它 cnpm lan commonjs pos 重量級框架 安裝vue.js的方法 一、簡介 Vue.js 是什麽 Vue.js(讀音 /vju?/, 類似於 view) 是一套構建用戶界面的 漸進式框架。與其他重量級框架不同的是

    軟件需求分析方法

    2.6 業務層 而且 客戶 數據類型 追蹤 回顧 經驗 矛盾 軟件需求分析(Software Reguirement Analysis)是研究用戶需求得到的東西,完全理解用戶對軟件需求的完整功能,確認用戶軟件功能需求,建立可確認的、可驗證的一個基本依據。 軟件需求分析是一

    TCP建立連接三次握手和釋放連接四次握手

    eight 請求 置1 計時器 響應 發送數據 出現 期望 本地 在談及TCP建立連接和釋放連接過程,先來簡單認識一下TCP報文段首部格式的的幾個名詞(這裏只是簡單說明,具體請查看相關教程) 序列號seq:占4個字節,用來標記數據段的順序,TCP把連接中發送的所有數

    Django中使用POST方法獲取POST數據

    class 需要 request www ict .html bsp 請求 post 1.獲取POST中表單鍵值數據 如果要在django的POST方法中獲取表單數據,則在客戶端使用JavaScript發送POST數據前,定義post請求頭中的請求數據類型:

    A*算法解決八數碼問題

    nim fir 空格 sin get () explore sed deepcopy from utils import ( PriorityQueue) import copy infinity = float(‘inf‘) def best_first_gr

    AndroidAS報錯解決方法:Non-static method '*' cannot be referenced from a static context

    轉載請註明出處,原文連結:https://blog.csdn.net/u013642500/article/details/80156306 【錯誤】 Non-static method '*' cannot be referenced from a static context

    Navicat Premium 12破解方法

    來源網址:https://www.jianshu.com/p/42a33b0dda9c 1、按步驟安裝Navicat Premium,如果沒有可以去官網下載:http://www.navicat.com.cn/download/navicat-premium 2、安裝好後下載啟用檔案:https://pa

    TCP 解決

    TCP 粘包:什麼是粘包現象 :   TCP粘包是指傳送方傳送的若干包資料到接收方接收時粘成一包,從接收緩衝區看,後一包資料的頭緊接著前一包資料的尾。 為什麼出現粘包現象 : (1) 傳送方原因   我們知道,TCP預設會使用Nagle演算法。而Nagle演算法主要做兩件事: &n

    Dom節點操作常用方法

    1.訪問/獲取節點 document.getElementById(id);           //返回對擁有指定id的第一個物件進行訪問 document.getElementsByName(name);      //返回帶有指定名稱的節點集合   注意拼寫:Elements docum

    轉載安裝RPM解決依賴的問題

    當下載了一個rpm包需要安裝其相關的依賴包時 yum --nogpgcheck localinstall packagename.arch.rpm  將自動安裝已經通過系統YUM儲存庫可用的所有依賴項

    data augmentation 資料增強方法總結

    1、問題描述 收集資料準備微調深度學習模型時,經常會遇到某些分類資料嚴重不足的情況,另外資料集過小容易造成模型的過擬合。 本文參考一些網友對於資料增強方法的一些tips,後續會附上自己實現的C++程式碼; 2、data augmentation常用方法 Color Jittering:對顏色的資料增強:影

    JAR檔案及命令的使用

    1.   JAR   檔案包      JAR   檔案就是   Java   Archive   File,顧名思意,它的應用是與   Java   息息相關的,是   Java   的一種文件格式。JAR   檔案非常類似   ZIP   檔案——準確的說,它就是  

    Hyper-VVirtualBoxVMware沖突的解決方法

    列表 not 模擬 .html off 解決方法 have detect 命令 安裝Visual Studio以後可能會導致與VirtualBox、VMware產生沖突,這是因為安裝了Windows Phone SDK,沖突表現為: 打開VirtualBox、VMware

    Python的字典get方法:從字典中獲取一個值

    討論   想從一個字典獲得一個值,但是首先要確信這個值是否在這個字典裡?使用簡單有效的get方法。   如果你試著用象d[x] 那樣的語法來獲得一個值,並且x的值不是字典d的鍵值, 你的嘗試將丟擲一個KeyError異常。 這個是經常有用的。如果你期望x的值是d中的一個鍵值,一個異常是通知你犯錯了的正確途徑

    MySQL修改時區的方法小結

    方法一:通過mysql命令列模式下動態修改 1.1 檢視mysql當前時間,當前時區 > select curtime(); #或select now()也可以 +-----------+ | curtime() | +-----------