我在c中使用tcp套接字服务器和客户端。 使用AF_INET,SOCK_STREAM和IPPROTO_TCP
我在客户端的发送功能
sent_now = send(sockId, buffer + sent_total, len - sent_total, MSG_DONTWAIT);
当我发送MSG达到20K-40KB的大小时,它工作正常。 当我发送MSG大小像365K(这就是我需要的)时,我在服务器端收到以下错误:资源暂时不可用!
我在服务器端的接收功能
totalRecvMsgSize = recieve(clntSocket,Buffer,RCVBUFSIZE,MSG_DONTWAIT);
我发送int数据类型。
如何在一次发送和接收操作中接收所有阵列?
旧帖子
有一篇文章What can cause a “Resource temporarily unavailable” on sock send() command,Davide Berra在那里说
那是因为您正在使用非阻塞套接字和输出 缓冲区已满。
来自send()手册页
当消息不适合发送缓冲区时 socket,send()通常阻塞,除非已放置套接字 在非阻塞I / O模式下。在非阻塞模式下,它将返回 在这种情况下,EAGAIN。
EAGAIN是绑定到"资源暂时不可用的错误代码"
考虑使用select()来更好地控制这种行为
我的问题是:
* 1)如何在一次发送和接收操作中接收所有阵列? *
2)select()会帮助我处理这个数组大小吗?
3)我可以更改缓冲区大小以及如何更改?
答案 0 :(得分:1)
由于这是一个流套接字,因此您在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;
}
}
答案 1 :(得分:0)
你无法可靠地实现这一目标。您始终可以编写自己的sendall
和recvall
函数,将套接字设置为阻塞,然后重复调用send
(/ recv
),直到发送/接收所有数据。 (通常带有阻塞套接字的单个send
调用将导致所有数据在一次操作中发送,但有些情况[例如传输某些数据后的信号]将导致早期返回,所以你不应该依赖它。)
您可以使用select
来实现与非阻塞套接字相同的功能,但它会使缓冲区管理变得更加复杂。您需要跟踪每个缓冲区中的位置/剩余的数据量,以及select
报告套接字“可读”或“可写”的新尝试时,在适当的位置发送/接收相应的缓冲区。
是的,您可以根据需要制作缓冲区大小,但如果您的意思是“我可以设置系统缓冲区大小以避免这种情况吗?”然后,没有办法配置系统,使其无需额外代码即可100%可靠地工作。 TCP不维护消息边界。您的协议必须在TCP提供的逻辑流上加上边界。