我正在用C++编写一个客户端应用程序,以便通过UDP广播接收二进制数据,但是,无论缓冲区大小如何,我都无法接收前4个字节以外的任何数据。我检查了Wireshark中的数据包,可以看到我的机器正在接收大约1200字节的数据。当我将其与我的客户端接收的数据进行比较时,我可以看到我正在接收数据包,但是剩余的数据丢失了。下面是我的代码:
#define BUFFERSIZE 4096
int main()
{
struct addrinfo hints, *servinfo, *p;
int sockfd, i, nbyt;
int *buf = (int*) malloc(BUFFERSIZE);
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;
getaddrinfo(NULL, "9011", &hints, &servinfo);
sockfd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol);
bind(sockfd, servinfo->ai_addr, servinfo->ai_addrlen);
FILE *file;
file = fopen("file.txt", "w+");
for (i=0;i<=45;i++)
{
nbyt = recv(sockfd, buf, BUFFERSIZE, 0);
fprintf(file, "%s %d; %s %x\n", "Bytes received:", nbyt, "Message:", *buf);
}
fclose(file);
close(sockfd);
free(buf);
printf("%s\n", "Execution ended.");
return 0;
}下面是我接收到的一些数据的示例:
Bytes received: 1131; Message: 5b0
Bytes received: 1131; Message: 5b3
Bytes received: 1131; Message: 5b6
Bytes received: 1092; Message: 4e0我尝试使用MSG_DONTWAIT标志将套接字设置为非阻塞,因为这解决了类似Python应用程序的问题,但这只会返回错误:
Bytes received: -1; Message: 0我对C++和套接字比较陌生,所以可能有一些我没有看到的东西。希望有人能帮我找出问题所在?如有必要,我可以提供更多信息。
发布于 2013-01-04 05:05:49
你能很好地收到它。您的调试代码并不像您所认为的那样工作。
printf的x说明符以十六进制打印无符号整型参数。您的平台上的整数可能是32位的。所以你只打印了前4个字节。
如果您想以十六进制打印整个缓冲区,则需要自己编写循环(当然,也可以使用库)。
例如,我警告你,我的C语言有点生疏了(到目前为止,这不是实现这一点的最佳方式)……此外,这还假设您的缓冲区始终是sizeof(int)的倍数,否则会丢失一些数据:
nbyt = recv(sockfd, buf, BUFFERSIZE, 0);
fprintf(file, "%s %d; %s\n", "Bytes received:", nbyt, "Message:");
for (offset = 0; offset < nbyt/sizeof(int); ++offset) {
fprintf(file, "%x ", buf[offset]);
}
fprintf(file, "\n");发布于 2013-01-04 05:13:27
代码中的*buf表示接收到的数据数组中的第一个整数,因此只打印接收到的UDP有效载荷的前四个字节。
发布于 2013-01-04 05:55:27
尽管存在前面提到的格式错误,但如果您收到一个'\0‘字符,则带有%s的格式化打印将在那里剪切字符串,而不管实际收到的字符数是多少。
为了调试纯文本,我使用了以下代码:
char escaped_char(char c)
{
char escapable[12] = {'\a','\b','\f','\n','\r','\t','\v','\\','\'','\"','\?','\0'};
char escaped[12] = { 'a', 'b', 'f', 'n', 'r', 't', 'v','\\','\'','\"', '?', '0'};
const char* escapable_end = escapable + 12;
const char* ec;
for(ec = escapable;ec != escapable_end;++ec)
{
if(c == *ec) return escaped[ec-escapable];
}
return 0;
}
/**
* @param buf input buffer to escape
* @param len length of contents in buf
* @param outlen pointer to an integer, which receives the length of the returned string
* @return A newly allocated, C style escaped string, NULL on error
* @warning A returned string must be freed with free()
*/
char* aescape(const char* buf,size_t len,size_t* outlen)
{
const char* buf_end = buf + len;
const char* c;
char ec;
char* result;
assert(buf && outlen);
(*outlen) = len;
for(c = buf;c != buf_end;++c)
{
if(escaped_char(*c))
{
++*outlen;
}
}
result = malloc((*outlen)+1);
assert(result != NULL);
if(result)
{
if((*outlen) > len)
{
char* out = result;
for(c = buf;c != buf_end;++c)
{
ec = escaped_char(*c);
if(ec)
{
*out++ = '\\';
*out++ = ec;
}
else
{
*out++ = *c;
}
}
}
else
{
memcpy(result,buf,len);
}
result[(*outlen)] = '\0';
}
else
{
(*outlen) = 0;
}
return result;
}https://stackoverflow.com/questions/14147173
复制相似问题