我在C中遇到Socket问题
数据包大小在sock选项中设置为3072
,如下所示:
int recvBuff = 3072;
int recvLowAt = 2;
if (setsockopt(sock, SOL_SOCKET, SO_RCVLOWAT, &recvLowAt, sizeof(recvLowAt)) < 0) {
LOGE("Error setsockopt rcvlowat -> %s\n", strerror(errno));
close(sock);
return -1;
}
if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &recvBuff, sizeof(recvBuff)) < 0) {
LOGE("Error setsockopt rcvbuf -> %s\n", strerror(errno));
close(sock);
return -1;
}
有时候数据包是< 3072
,即使它小于3072
if ((size = recv(sock, buffer, BUFF_SIZE, 0)) < 0) {
LOGE("Error recv -> %s\n", strerror(errno));
size = 0;
} else {
LOGI("%d bytes received\n", size);
}
输出是:
1448 bytes received
2896 bytes received
1448 bytes received
我想要一个像这样的输出:
Output is :
3072 bytes received
3072 bytes received
3072 bytes received
500 bytes received
Whole data has been sended !
我尝试在MSG_WAITALL
中使用recv
作为标记,但最后一个数据包未被发送...
我可以帮忙吗? 谢谢!
答案 0 :(得分:0)
套接字recv调用并不总是返回发送方在其发送调用中发送的所有数据。 如果你有完整的数据,你需要继续调用recv并检查长度或数据内容
答案 1 :(得分:0)
即使它不到3072,我也希望得到它
你会。
我想要像这样的输出
你没赢。在阻塞模式下,TCP不必一次传输多个字节。如果您想同时使用3072(或其他)字节,则必须循环。
NB引用的两个陈述是相互矛盾的。
答案 2 :(得分:0)
需要完全填充缓冲区是一种罕见的情况,通常不需要在内核端实现。要在用户空间中实现它,您只需将此代码添加到您的代码中(它只有三行代码!!!):
unsigned char buffer[SIZE_OF_BUFFER]; /* this is the buffer */
int n, /* auxiliary variable */
bsz = 0; /* <-- actual buffer size */
/* just loop reading until the whole buffer is full of data, or EOF or ERROR */
while (bsz < sizeof buffer &&
(n = recv(socket, buffer + bsz, sizeof buffer - bsz, flags)) > 0)
bsz += n; /* see NOTE */
/* here, (bsz >= sizeof buffer) || (n <= 0), ==> BUFFER FULL, EOF in socket, or some other error happened */
if (n < 0) {
/* process error command */
} else if (n == 0) {
/* process EOF in connection */
} else {
/* process a completely filled buffer */
}
这也可以作为for
循环实现:
for(bsz = 0;
bsz < sizeof buffer &&
(n = recv(socket, buffer + bsz, sizeof buffer - bsz, flags)) > 0;
bsz += n) continue; /* used continue; as only ; for an empty loop body is weird */
嗯,断言(bsz >= sizeof buffer)
实际上更具限制性,可以写成(bsz == sizeof buffer)
,因为recv
系统调用始终保证返回值小于或等于请求的字节数。这导致在执行循环体后new_bsz <= old_bsz + (sizeof buffer - old_bsz)
或new_bsz <= sizeof buffer
。最后,两个断言都是正确的(bsz >= sizeof buffer
和bsz <= sizeof buffer
,这意味着bsz == sizeof buffer
)。的 QED 强>