我在c中使用tcp套接字服务器和客户端,使用AF_INET、SOCK_STREAM和IPPROTO_TCP。
我在客户端中的发送功能
sent_now = send(sockId, buffer + sent_total, len - sent_total, MSG_DONTWAIT);当我发送到20K-40 It大小的MSG时,它工作得很好。当我将MSG发送到365 K大小(我需要的东西)时,我在服务器端收到以下错误:资源暂时不可用!
在服务器端我的接收功能
totalRecvMsgSize =接收( clntSocket,Buffer,RCVBUFSIZE,MSG_DONTWAIT);
我发送int数据类型。
如何在一次发送和接收操作中接收所有数组?
老岗位
有一篇关于What can cause a “Resource temporarily unavailable” on sock send() command的文章,大卫·贝拉说
这是因为您使用的是非阻塞套接字,并且输出缓冲区已满。 从send()手册页 当消息不适合套接字的发送缓冲区时,send()通常会阻塞,除非套接字已处于非阻塞I/O模式。在非阻塞模式下,在这种情况下它将返回EAGAIN。EAGAIN是与“资源暂时不可用”相关联的错误代码 考虑使用select()来更好地控制这种行为
我的问题是:
*1)如何在一次发送和接收操作中接收所有数组?*
2) select()是否帮助我实现这个数组大小?
3)我可以更改缓冲区大小以及如何更改吗?
发布于 2016-10-10 16:26:23
因为这是流套接字,所以在send()上使用循环,在recv()上使用MSG_WAITALL。
考虑以下帮助函数:
/* Receive the entire buffer.
* Returns 0 if success, nonzero errno otherwise.
*/
static int recv_all(const int sockfd, void *buffer, const size_t len)
{
ssize_t n;
n = recv(sockfd, buffer, len, MSG_WAITALL);
if (n == 0)
return errno = EPIPE; /* Other end will not send more data */
else
if (n == -1)
return errno;
else
if (n < -1)
return errno = EIO; /* Should never occur */
else
if (n != (ssize_t)len)
return errno = EINTR; /* Interrupted, or sender goofed */
else
return 0;
}
/* Send the entire buffer.
* Returns 0 if success, nonzero errno otherwise.
*/
static int send_all(const int sockfd, const void *buffer, const size_t len)
{
const char *pos = (const char *)buffer;
const char *const end = (const char *)buffer + len;
ssize_t n;
while (pos < end) {
n = send(sockfd, pos, (size_t)(end - pos), 0);
if (n > 0)
pos += n;
else
if (n != -1)
return errno = EIO;
else
return errno;
}
}发布于 2016-10-10 16:24:19
sendall和recvall函数,这些函数将套接字设置为阻塞,然后反复调用send (/recv),直到发送/接收所有数据。(通常,带有阻塞套接字的单个send调用将导致在一次操作中发送所有数据,但在某些数据传输后会出现情况信号,例如,这将导致早期返回,因此不应依赖于此。)select来实现与非阻塞套接字相同的功能,但它使缓冲区管理更加复杂。您需要跟踪您在每个缓冲区中的位置/保留了多少数据,并且当select报告一个套接字是“可读的”或“可写的”时,请重新尝试在相应缓冲区的适当位置发送/接收。https://stackoverflow.com/questions/39959115
复制相似问题