我在平台上运行TCP服务器,该平台从缓冲区读取字节,并通过一次发送调用在网络上发送所有字节:
send(sSocket.client_sock, base, frb_size, 0);
frb_size的大小为2_228_224个字节。
在接收端,我试图缓冲数据:
while(1) {
while(total != size) {
r = recv(my_socket->sock, buf, 8192-total, 0);
memcpy(buffer+total, buf, r);
total += r;
}
//some code dealing with manipulating the buffer with SDL
}
我有一个较小的缓冲区buf
,大小为8192.读取时,它使用memcpy将其放入缓冲区内的正确位置,大小为2_228_224。
我的问题是,在第一次迭代之后,所有进行的迭代都返回r为0,这意味着套接字已按文档关闭。同样奇怪的是,无论我使用什么大小的buf
,它总是在第一次迭代时返回完整的字节数。例如,在上面的代码中将返回8192个字节,如果我将大小更改为65507,它将返回65507,但如果我将其更改为2_228_224,它将永远不会返回完整的缓冲区。
与此同时:
while(1) {
r = recv(my_socket->sock, buffer, size, 0);
//some code dealing with manipulating the buffer with SDL
}
其中size是缓冲区的大小(2_228_224)。 r在调试时永远不会返回0,但它也不会有构成发送输入的完整字节数。
我在Windows上的套接字API上做错了吗?有没有办法让Winsock套接字阻塞直到收到所有字节数?
感谢。
答案 0 :(得分:2)
正如评论中所述,使用8192-total
是不对的。要准确读取size
个字节,请使用以下内容:
while(total < size) {
int bytes = size - total;
if (bytes > 8192) bytes = 8192;
r = recv(my_socket->sock, buf, bytes, 0);
if (r <= 0) {
/* handle this! */
break;
}
memcpy(buffer+total, buf, r);
total += r;
}
在每次迭代时,它会尝试读取总数中剩余的字节数,但是会以输入缓冲区的大小为上限。
在循环中处理r <= 0
和break
以避免无限循环(如果重复r == 0
)或段错误(如果r == -1
重复推送{{} 1}}否定)。