我目前正在使用網絡的項目。我必須發送一個結構通過C++中的套接字的數據
struct Header
{
uint32_t magic;
uint32_t checksum;
uint32_t timestamp;
uint16_t commandId;
uint16_t dataSize;
};
struct Packet
{
struct Header header;
char data[128];
};
我試圖從一個套接字發送結構數據包到另一個使用TCP。我試圖把我的結構一樣,
send(socket, &my_struct, sizeof(my_struct), 0);
但它不工作,所以我已經試過*
unsigned char *Serialization::serialize_uint32(unsigned char *buffer, uint32_t arg)
{
buffer[3] = (arg >> 24);
buffer[2] = (arg >> 16);
buffer[1] = (arg >> 8);
buffer[0] = (arg);
return (buffer + sizeof(uint32_t));
}
unsigned char *Serialization::serialize_uint16(unsigned char *buffer, uint16_t arg)
{
buffer[1] = (arg >> 8);
buffer[0] = (arg);
return (buffer + sizeof(uint16_t));
}
unsigned char *Serialization::deserialize_uint32(unsigned char *buffer, uint32_t *arg)
{
memcpy((char*)arg, buffer, sizeof(uint32_t));
return (buffer + sizeof(uint32_t));
}
unsigned char *Serialization::deserialize_uint16(unsigned char *buffer, uint16_t *arg)
{
memcpy((char*)arg, buffer, sizeof(uint16_t));
return (buffer + sizeof(uint16_t));
}
即使在客戶端symply發送結構序列化我的結構到一個char當我讀取服務器端時,標頭數據已損壞 爲什麼數據損壞?
客戶端發送環路
TcpSocket tcp;
Packet p;
std::stringstream ss;
int cpt = 0;
int ret = 0;
char *serialized;
tcp.connectSocket("127.0.0.1", 4242);
while (getchar())
{
ss.str("");
ss.clear();
ss << cpt++;
p.header.magic = 0;
p.header.checksum = 1;
p.header.timestamp = 2;
p.header.commandId = 3;
p.header.dataSize = ss.str().length();
memset(p.data, 0, 128);
memcpy(p.data, ss.str().c_str(), ss.str().length());
serialized = new char[sizeof(Header) + ss.str().length()];
bzero(serialized, sizeof(Header) + ss.str().length());
Serialization::serialize_packet(serialized, p);
hexDump("serialized", serialized+1, sizeof(Header) + ss.str().length());
ret = tcp.write(serialized+1, sizeof(Header) + ss.str().length());
}
服務器的recv循環:
buff = new char[bav];
socket->read(buff, bav);
hexdump("buff", buff, bav);
(通過select()調用fonction)插座 - >閱讀():
int TcpSocket::read(char *buff, int len)
{
int ret;
ret = recv(this->_socket, buff, len, 0);
return (ret);
}
當我運行那些方案:
./server
[Server] new connexion :: [5]
recv returns : 17
buff serialized:
0000 00 00 00 00 14 00 00 00 1c 00 00 00 1a 00 00 00 ................
0010 1b
./client
serialized data:
0000 00 00 00 00 00 00 01 00 00 00 02 00 03 00 01 30 ...............0
0010 00
send returns : 17
我們是否假定客戶端是用適當的反向算法解壓縮的(注意你應該使用'unsigned char'作爲你的包緩衝區)。另外,第一種情況下的結構打包以及機器端格式*將起作用。 – WhozCraig
對於uint16和uint32,您可以使用ntohl,ntohs,htonl和htons。簡短的答案是這樣的:您必須在字節級精確定義數據格式,並且在發送和接收時正確地將數據格式轉換爲「有線格式」或從該格式轉換而來。 –
@DavidSchwartz我同意,但是當我在幾天前提出這個問題的時候,由於它不在「標準」中,所以我總結了一個問題。仍然從那一個刺痛(我仍然會用POSIX函數來做,無論順便說一句,就像你可能會那樣)。 – WhozCraig