C 通过套接字序列化打包和发送二进制数据时出现问题
为了让我的程序能够正确地发送/打包和接收/解包我的数据,我已经进行了几个小时的尝试、调试和测试。我唯一的希望就是得到一些好的帮助 为了打包/解包数据,我实施了Beej的网络编程指南 代码打包/解包在同一程序内部工作。但是,当我试图通过套接字将打包的数据发送到同一台计算机上的另一个程序时,它将不起作用!我的想法是recv()和send()函数在某种程度上可能会导致数据损坏或类似的情况,我尝试了几种调试方法: 我需要一些帮助来实现这一点,我认为问题在于buf的发送和接收方式,因为pack()/unpack()函数在程序内部工作。 谢谢 客户端:C 通过套接字序列化打包和发送二进制数据时出现问题,c,sockets,serialization,C,Sockets,Serialization,为了让我的程序能够正确地发送/打包和接收/解包我的数据,我已经进行了几个小时的尝试、调试和测试。我唯一的希望就是得到一些好的帮助 为了打包/解包数据,我实施了Beej的网络编程指南 代码打包/解包在同一程序内部工作。但是,当我试图通过套接字将打包的数据发送到同一台计算机上的另一个程序时,它将不起作用!我的想法是recv()和send()函数在某种程度上可能会导致数据损坏或类似的情况,我尝试了几种调试方法: 我需要一些帮助来实现这一点,我认为问题在于buf的发送和接收方式,因为pack()/unp
unsigned char buf[1024];
int16_t packetsize = pack(buf, "h", (int16_t)37);
packi16(buf+1, packetsize);
int len = packetsize;
uint16_t header = htons(packetsize); //Convert from host -> network
//Sends info to receiver about next pack coming.
printf("HEADER SIZE %d\n", packetsize);
if(send(sock, &header, packetsize, 0) == -1) {
perror("sendall");
}
/*==========SEND PACKAGE======================*/
int bytessendt = send(sock, buf, len, 0);//server_send_all(sock, buf, &len);
if(bytessendt == -1) {
perror("sendall");
}
printf("BYTES SENT OVER SOCKET: %d \n", bytessendt);
close(sock);
uint16_t buf;
int len = sizeof(buf);
if(recv(i, &buf, len, 0) == -1) {
printf("****Error when receiving");
}
int header = ntohs(buf);
printf("HEADER SIZE: %d\n", header);
/*========REICIVE PACK AND UNPACK================*/
unsigned char buf2[1024];
int16_t monkeycount;
int bytesreaded = recv(i, buf2, header, 0);
if(bytesreaded == -1) {
printf("Feil ved mottakelse\n");
}
printf("BYTES READED: %d\n", bytesreaded);
printf("BYTES SHOULD BE READED: %d\n", header);
unpack(buf2, "h", &monkeycount);
printf("CONTENT: %d\n", monkeycount);
close(i);
int server_send_all(int socket, unsigned char *buf, int *len) {
int total = 0; //Total amout of data to send
int bytesleft = *len; //Amount of data left to send
int n; //Holds return from send()
printf("SOCKET -DATA TO SEND: %d\n", *len);
while(total < *len) {
n = send(socket, buf+total, bytesleft, 0);
if(n == -1) { //send() returns error
break;
}
total += n;
bytesleft -= n;
}
*len = total; //Returns actually sent
return n == -1?-1:0;
}
服务器端:
unsigned char buf[1024];
int16_t packetsize = pack(buf, "h", (int16_t)37);
packi16(buf+1, packetsize);
int len = packetsize;
uint16_t header = htons(packetsize); //Convert from host -> network
//Sends info to receiver about next pack coming.
printf("HEADER SIZE %d\n", packetsize);
if(send(sock, &header, packetsize, 0) == -1) {
perror("sendall");
}
/*==========SEND PACKAGE======================*/
int bytessendt = send(sock, buf, len, 0);//server_send_all(sock, buf, &len);
if(bytessendt == -1) {
perror("sendall");
}
printf("BYTES SENT OVER SOCKET: %d \n", bytessendt);
close(sock);
uint16_t buf;
int len = sizeof(buf);
if(recv(i, &buf, len, 0) == -1) {
printf("****Error when receiving");
}
int header = ntohs(buf);
printf("HEADER SIZE: %d\n", header);
/*========REICIVE PACK AND UNPACK================*/
unsigned char buf2[1024];
int16_t monkeycount;
int bytesreaded = recv(i, buf2, header, 0);
if(bytesreaded == -1) {
printf("Feil ved mottakelse\n");
}
printf("BYTES READED: %d\n", bytesreaded);
printf("BYTES SHOULD BE READED: %d\n", header);
unpack(buf2, "h", &monkeycount);
printf("CONTENT: %d\n", monkeycount);
close(i);
int server_send_all(int socket, unsigned char *buf, int *len) {
int total = 0; //Total amout of data to send
int bytesleft = *len; //Amount of data left to send
int n; //Holds return from send()
printf("SOCKET -DATA TO SEND: %d\n", *len);
while(total < *len) {
n = send(socket, buf+total, bytesleft, 0);
if(n == -1) { //send() returns error
break;
}
total += n;
bytesleft -= n;
}
*len = total; //Returns actually sent
return n == -1?-1:0;
}
到服务器:
给出输出
内容:37 Hello Wor您打包了一个2字节的
int16\u t
,然后您只将buf
增加1个字节,应该是2个字节:
int16_t packetsize = pack(buf, "h", (int16_t)37);
packi16(buf+2, packetsize);
每次将某些内容打包到缓冲区时,再次调用pack()
时,应将缓冲区指针增加该数量:
pack(buf, 2 bytes);
pack(buf+2, 4 bytes);
pack(buf+6, 2 bytes);
...
所以我觉得你应该这样做:
int packetsize =0;
packetsize += pack(buf+packetsize, "h", (int16_t)37);
packetsize += pack(buf+packetsize, "h", (int16_t)38);
...
Note1:packetsize
应该是int
,因为pack()
返回int
,我不明白为什么第二次使用packi16()
而不是更通用的pack()
函数
注意2:数据包大小也错误,您忘记添加
packetsize
的大小。事实上,我认为您根本不是要将数据包大小添加到数据包中,因为您分别发送数据包大小和数据包,您打包了一个2字节的int16\u t
,然后仅将buf
增加1个字节,应该是2个字节:
int16_t packetsize = pack(buf, "h", (int16_t)37);
packi16(buf+2, packetsize);
每次将某些内容打包到缓冲区时,再次调用pack()
时,应将缓冲区指针增加该数量:
pack(buf, 2 bytes);
pack(buf+2, 4 bytes);
pack(buf+6, 2 bytes);
...
所以我觉得你应该这样做:
int packetsize =0;
packetsize += pack(buf+packetsize, "h", (int16_t)37);
packetsize += pack(buf+packetsize, "h", (int16_t)38);
...
Note1:packetsize
应该是int
,因为pack()
返回int
,我不明白为什么第二次使用packi16()
而不是更通用的pack()
函数
注意2:数据包大小也错误,您忘记添加
packetsize
的大小。事实上,我认为您根本不是要将数据包大小添加到数据包中,因为您分别发送数据包大小和数据包,解包代码需要一个int*
参数来解包int16\t
:将声明更改为int monkeycount
解包代码需要一个int*
参数来解包int16\t
:将声明更改为int monkeycount代码>错误是什么?预期的行为是什么?说它不起作用是不够的。预期的行为是printf(“内容:%d\n”,monkeycount);应打印37,打开包装时monkeycount应保持37。我相信server_send_all()函数负责发送所有数据?它实际打印的是什么?您忘记再次增加buf指针:)当然,我不明白为什么我们增加buf指针:}代码现在增加buf指针,服务器端现在删除最后两个字符:(错误是什么?预期的行为是什么?说它不起作用是不够的。预期的行为是printf(“内容:%d\n”,monkeycount);应该打印37,解包时monkeycount应该保存37。我相信服务器发送所有()函数负责发送所有数据?它实际打印的是什么?您忘了再次增加buf指针:)当然,我不明白为什么要增加buf指针:}代码现在增加buf指针,服务器端现在删除最后两个字符:(谢谢,这确实有效,monkeycount在服务器端可容纳37个!我是否必须根据我发送的数据的数量/数量来更改我的buf增量?@user265767是的,每次向缓冲区添加内容时,在再次调用pack时,按该数量递增指针。检查更新的应答我现在已经更改了代码,因此需要我也尝试过打包一个C字符串,在服务器端字符串上,所有字符串的前两个字母都会被删除,而不管长度如何。原因可能是什么?您是否在前两个字符上编码了字符串长度或其他内容?不,我不知道。在打包时添加了输出()C字符串。谢谢,这确实有效,monkeycount在服务器端可容纳37个字符!我是否必须根据我发送的数据的数量/数量来更改buf的增量?@user265767是的,每次向缓冲区添加内容时,再次调用pack时,将指针的增量增加该数量。检查更新的应答我现在已更改代码,以便考虑到你说的话。我也尝试过打包一个C字符串,在服务器端字符串上,所有字符串的前两个字母都会被删除,不管长度如何。原因可能是什么?你是否在前两个字符上编码了字符串长度或其他什么?不,我不知道。打包时添加了输出()/unpack()C字符串。