記錄一下TCP的客戶端的簡單拆包過程

場景:從服務端過來的數據很多,產生了粘包現象;現在根據對應的協議來進行拆包

思路:
Step1:找到幀頭,幀尾的位置
Step2:從buffer中取出幀數據,放到消息隊列中
Step3:循環從buffer裏面取數據,注意起始位置的變化 goto Step1

循環結束的條件:buffer裏面的長度 和 最後找到幀尾的數據相同

簡單的代碼實現:(這段只是針對那種多幀粘包的情況,對於缺包,其餘的情況還沒處理)
這裏處理的就是 幀頭:0x0A,0x7F  幀尾:0x0D 0x0A

示例代碼:(這裏代碼片段)

	    while (1)
		{
			for (i = datalen; i < len; i++)
			{
				if (0xAA == buffer[i] && 0x7F == buffer[i + 1])
				{
					iStart = i;
				}

				if (0x0D == buffer[i] && 0x0A == buffer[i + 1])
				{
					iEnd = i+1;
					break;
				}
			}

			for (j = iStart; j <= iEnd; j++)
			{
				message.Recvbuffer[j - iStart] = buffer[j];
			}

			//將分包的數據push到消息隊列中
			message.msgType = SOCKMSG;
			if (-1 == (msgsnd(pData->qid, &message, iEnd-iStart+1, 0)))
			{
				perror("msg closed! quit the system!\n");
				bflag = true;
				break;
			}

			memset(message.Recvbuffer, 0, MAX_BUF_SIZE);

			datalen = iEnd;

			if ((iEnd + 1) == len)
			{
				iStart = 0;
				iEnd = 0;
				datalen = 0;
				printf("Process Success!\n");
				break;
			}
			printf("iEnd:%d\n", iEnd);
			iStart = 0;
			iEnd = 0;

		}

簡單來解釋下這段代碼:

buffer表示從server收過來的包,裏面可能包含若干個包;

輸出的結果示例:

AA 7F 00 00 04 72 65 65 19 51 5D 5D 61 40 54 5C 67 53 5F 6B 53 70 65 65 54 61 6C 6B 53 70 3C 9F 0D 0A
AA 7F 00 00 04 71 65 65 19 51 5D 5D 61 40 54 5C 67 53 5F 6B 53 70 65 65 54 61 6C 6B 53 70 C3 D4 0D 0A
AA 7F 00 00 04 73 65 65 19 51 5D 5D 61 40 54 5C 67 53 5F 6B 53 70 65 65 54 61 6C 6B 53 70 68 66 0D 0A
AA 7F 00 00 04 74 65 65 19 51 5D 5D 61 40 54 5C 67 53 5F 6B 53 70 65 65 54 61 6C 6B 53 70 C2 08 0D 0A
AA 7F 20 00 60 5A 65 65 19 51 5D 5D 61 40 54 5C 67 53 5F 52 62 49 51 53 64 50 5C 5B 61 40 5C 56 66 52 6C 6B 53 70 65 65 54 61 6C 6B 53 70 65 65 54 61 6C 6B 53 70 65 65 54 61 6C 6B 53 70 27 FE 0D 0A
 

類似這種結果

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章