【发布时间】:2010-06-16 10:48:17
【问题描述】:
我想知道:在 C 中使用套接字 (AF_UNIX) 进行编程时,在向套接字发送或从套接字接收数据时是否有任何限制(以字节为单位)?
【问题讨论】:
我想知道:在 C 中使用套接字 (AF_UNIX) 进行编程时,在向套接字发送或从套接字接收数据时是否有任何限制(以字节为单位)?
【问题讨论】:
您可以使用setsockopt(SO_SNDBUF 和SO_RCVBUF)为每个单独的套接字连接更改读取和写入缓冲区。
默认和最大尺寸取决于平台。
此外,如果您为每个单独的读取提供更大的用户端缓冲区,例如recv。
如果您依次使用多个recvs,您可以通过连接读取无限量的字节,这将花费无限长。
【讨论】:
sockets 行为是依赖于实现的。通常,当您 send() 时,无法保证将多少字节推送到套接字上。由于内核对此进行控制,因此它可以是任意数字,通常在 1500 或更少的范围内。所以你需要做的是检查 send() 返回代码并继续将数据推送到套接字上,直到你完成。此示例假定您已将套接字设置为非阻塞:
fcntl(s, F_SETFL, O_NONBLOCK);
int sendall(int s, char *buf, int *len)
{
int total = 0; /* how many bytes we've sent */
int bytesleft = *len; /* how many we have left to send */
int n=0;
int retries=0;
struct timespec tp={0,500};
while(total < *len)
{
n = send(s, buf+total, bytesleft, 0);
if (n == -1)
{
/* handle errors here,
plus check for EWOULDBLOCK
and then nanosleep()
*/
}
total += n;
bytesleft -= n;
}
回答您的问题 - 不,没有限制,您不能通过一次 send() 调用发送所有数据。
【讨论】:
send(2),这在不同的操作系统上有所不同,但通常大于一帧(并且您在计算中忘记了 IP 和 TCP 或 UDP 标头); b) 非阻塞和 nanosleep - 您只是在模拟阻塞发送,但不会让操作系统在发送缓冲区空间可用时唤醒您。 去掉这段代码,在 Solaris 上使用/dev/poll。