起始標誌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;
}
}
}