[英]Variable length Message over TCP Socket in C++
我試圖向服務器發送一些長度前綴數據,我已經通過使用其他人在堆棧溢出時發布的代碼和解決方案更加努力。 仍在尋找使用TCP實際工作的東西。我不太了解(關於網絡編程,但我知道理論概念)。 我正在寫我到目前為止所嘗試的內容。基於此我有一些問題。
因為我們在客戶端使用Char Buffer[200] = "This is data"
來發送(使用send()
函數)字符串和char類型數據到服務器(使用recv()
函數接收)。 直到這里沒關系,但如果我需要發送一些帶有長度信息的可變長度消息呢? ,我如何編碼長度信息到消息?
for example: 0C 54 68 69 73 20 69 73 20 64 61 74 61 07 46 72 6f 6d 20 6d 65
(length) T h i s i s d a t a (length) F r o m m e
How can i interpret these two message seperately from tcp stream at the sever side ?
我不知道如何發送長度信息? 或者,如果有人能夠理解我的測試用例(在下面的編輯中給出)來驗證字符串的長度信息。
編輯:似乎沒關系,但我只需要驗證一下前綴長度。 我發送20個字節(“這是我的數據”)到服務器。 我收到的長度大小是4個字節(我不知道里面是什么,我需要驗證我收到的4字節長度是否包含0000 0000 0000 0000 0000 00000 0001 0100)。 多數民眾贊成它,所以我認為通過將長度信息移動2位來驗證它的方式現在應該看起來像(我收到的4個字節長度包含0000 0000 0000 0000 0000 00000 0000 0101)在這種情況下我應該只得到5個字符即“這個”。 你知道我怎么能在服務器端驗證這個?
客戶代碼
int bytesSent;
int bytesRecv = SOCKET_ERROR;
char sendbuf[200] = "This is data From me";
int nBytes = 200, nLeft, idx;
nLeft = nBytes;
idx = 0;
uint32_t varSize = strlen (sendbuf);
bytesSent = send(ConnectSocket,(char*)&varSize, 4, 0);
assert (bytesSent == sizeof (uint32_t));
std::cout<<"length information is in:"<<bytesSent<<"bytes"<<std::endl;
// code to make sure all data has been sent
while (nLeft > 0)
{
bytesSent = send(ConnectSocket, &sendbuf[idx], nLeft, 0);
if (bytesSent == SOCKET_ERROR)
{
std::cerr<<"send() error: " << WSAGetLastError() <<std::endl;
break;
}
nLeft -= bytesSent;
idx += bytesSent;
}
bytesSent = send(ConnectSocket, sendbuf, strlen(sendbuf), 0);
printf("Client: Bytes sent: %ld\n", bytesSent);
服務器代碼
uint32_t nlength;
int length_received = recv(m_socket,(char*)&nlength, 4, 0);
char *recvbuf = new char[nlength];
int byte_recived = recv(m_socket, recvbuf, nlength, 0);
謝謝
如果需要發送可變長度數據,則需要在數據本身之前發送該數據的長度。
在上面的代碼片段中,您似乎正在執行相反的操作:
while (nLeft > 0)
{
bytesSent = send(ConnectSocket, &sendbuf[idx], nLeft, 0);
// [...]
}
bytesSent = send(ConnectSocket, sendbuf, strlen(sendbuf), 0);
在這里首先發送字符串,然后發送長度。 客戶如何能夠解釋這一點? 到達長度時,他們已經將繩子拉出插座。
相反,首先發送長度,並確保明確大小字段的大小:
const uint32_t varSize = strlen (sendbuf);
bytesSent = send(ConnectSocket, &varSize, sizeof (varSize), 0);
assert (bytesSent == sizeof (uint32_t));
while (nLeft > 0)
{
bytesSent = send(ConnectSocket, &sendbuf[idx], nLeft, 0);
// [...]
}
您可能還會考慮根本不發送可變長度數據。 通常,固定寬度的二進制協議在接收端更容易解析。 您總是可以在固定寬度的字段中發送字符串數據(例如,20個字符),並用空格或\\0
填充它。 這確實在線上浪費了一些空間,至少在理論上是這樣。 如果您對固定寬度字段的大小以及您在其中發送的內容非常了解,那么在許多情況下您可以使用此空間。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.