如何發送和接收應用層數據包?

當兩臺電腦要通過網絡)傳輸數據的時候,應用層必須要制定好自己的頭部,最簡單的頭部可以是這樣(以傳輸圖片爲例):

起始標誌0xFFEF(short類型,表明這是一個包的開頭)+圖片數據長度(int類型,4個字節)+圖片數據(完整的圖片數據)


發送端和接收端的C代碼大致如下:


發送端代碼:

void sendPic(int len, char* picData)  // len是圖片大小, picData是圖片在內存中的起始地址
{
    int totalLen = sizeof(short) + sizeof(int) + len;  //這是整個包長
    char* appData = new char[totalLen ];
    memcpy(appData , htons(0xFFEF), sizeof(short));
    memcpy(appData + sizeof(short), htohl(len), sizeof(int));
    memcpy(appData + sizeof(short) + sizeof(int), picData, len);
    send(s, appData, totalLen, 0);
}

接收端代碼:
#define BUFSIZE 1024*1024
#define ONCE_RCV_LEN 1500
void recvPic()
{
    // 下面分配的內存是用於接收數據的,會循環使用
    char* picPacket = new char[BUFSIZE ];

    int readPos = 0;          // 讀數據的位置
    int writePos = 0;         // 寫數據的位置
    // 下面這個循環就是用於循環接收圖片的
    while(true)
    {
         int len = recv(s, picPacket + writePos, ONCE_RCV_LEN, 0);
         writePos += len; 
         // 下面的循環是用來找到數據包的起始位置的,有時會有一些無效數據存在,需要跳過
         while( ntos(short(picPacket + readPos)) != 0xFFEF)
               readPos++;
         readPos += sizeof(short);
         int picLen = ntohl(int(picPacket + readPos));  // 取出圖片長度
         readPos += sizeof(int);
         if(writePos - readPos < picLen)  // 當圖片尚未完全接收完的時候,要繼續接收剩餘部分
         {
              len = recv(s, picPacket + writePos, picLen - (writePos - readPos));
              writePos += len;
         } 
         displayPic(picPacket + readPos, picLen);  //這個函數用來顯示圖片的,只是個示例
         readPos += picLen;
        
        // 當剩餘緩存不夠接收下一批數據的時候,將尚未讀取的數據copy到接收緩存頭部
         if(writePos + ONCE_RCV_LEN > BUFSIZE) 
         {
               memcpy(picPacket, picPacket + readPos, writePos - readPos);
               readPos = 0;
               writePos =  writePos - readPos;
         }
    }
}
發佈了2 篇原創文章 · 獲贊 3 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章