过去几天我正在使用套接字(在C中,没有套接字编程的经验)。 其实我必须收集树莓派上的WiFi数据包,做一些处理,并且必须通过套接字(这两个设备都连接到网络中)将格式化的信息发送到另一个设备。以C的速度在C中的套接字上接收不同长度的数据包的连续流?
我面临的挑战是通过套接字接收数据。
在发送数据时,数据通过发送端的套接字成功发送,但在接收端,有时会收到一些垃圾或以前的数据。
在发送端(客户端):
int server_socket = socket(AF_INET, SOCK_STREAM, 0);
//connecting to the server with connect function
send(server_socket, &datalength, sizeof(datalength),0); //datalength is an integer containing the number of bytes that are going to be sent next
send(server_socket, actual_data, sizeof(actual_data),0); //actual data is a char array containing the actual character string data
接收侧(服务器端):
int server_socket = socket(AF_INET, SOCK_STREAM, 0);
//bind the socket to the ip and port with bind function
//listen to the socket for any clients
//int client_socket = accept(server_socket, NULL, NULL);
int bytes;
recv(client_socket, &bytes, sizeof(bytes),0);
char* actual_message = malloc(bytes);
int rec_bytes = recv(client_socket, actual_message, bytes,0);
*上面的代码行是不实际代码行,但流量和程序是类似的(具有异常处理和评论)。
有时,我可以快速获取所有数据包的实际数据(没有任何错误和数据包丢失)。但有时候,字节(整数发送来说明下一个事务的字节流的大小)是作为一个垃圾值接收的,所以我的代码在那个时候被破坏了。 有时,我在接收端收到的字节数少于预期的字节数(从已收到的整数bytes
中得知)。所以在这种情况下,我检查这种情况并检索剩余的字节。
实际上数据包到达的速率非常高(大约在1000个数据包在不到一秒钟,我不得不解剖,格式化并通过套接字发送它)。我尝试了不同的想法(使用SOCK_DGRAMS,但这里有一些数据包丢失,在事务之间插入一些延迟,为每个数据包打开并关闭一个新套接字,在接收数据包后添加一个确认),但没有一个符合我的要求(快速传输丢包数为0的数据包)。
请注意,建议一种通过套接字快速发送和接收不同长度的数据包的方法。
什么是'actual_data'?它是*所有*充满数据?有没有部分填充的缓冲区?因为,你知道,TCP是一个*流*协议,没有固定大小的数据包或消息边界。这意味着你可能并不总是通过单一的“recv”调用发送所有这些内容,你必须循环以确保你能收到所有的数据。 –
此外,由于您正在发送数据长度的“int”值(我假设),您确定没有任何[* endianness *](https://en.wikipedia.org/wiki/Endianness)问题是什么?由于在典型的ARM平台(如R-PI)和典型的x86 PC平台(如大多数现代台式计算机)上的排序通常不相同。 –
@Someprogrammerdude'实际数据'就像一个英文文本(WiFi数据包解析和格式化) 是的......我知道它可能不会收到一次电话,因为我添加了一张支票,如果没有收到一个电话,我已经添加了代码来获取剩余的数据字节。 实际的问题是与字节的数量,它有时收到一些垃圾值 –