在 UDP 套接字上使用 write()/read()?

Posted

技术标签:

【中文标题】在 UDP 套接字上使用 write()/read()?【英文标题】:Using write()/read() on UDP socket? 【发布时间】:2015-01-10 15:55:16 【问题描述】:

根据手册页:

send() 和 write(2) 之间的唯一区别是标志的存在。使用零标志参数,send() 等效于 write(2)。此外,以下调用 send(sockfd, buf, len, flags);相当于 sendto(sockfd, buf, len, flags, NULL, 0);

recv() 调用通常仅在连接的套接字上使用(参见 connect(2)),它与带有 NULL src_addr 参数的 recvfrom() 相同。

另外,如果我没记错的话(在手册页中找不到),recvflags == 0 等效于 read(类似于 writesend)。


所以:

这是否意味着在 UDP 套接字上使用 read 非常好(如果我不需要 src_addr)? 有没有办法在 UDP 套接字上使用write(现在我在sendtodest_addr 参数中设置了目标地址)?

【问题讨论】:

@admdrew - 为什么不呢?这里没有具体的 C++(除了我对 socket_connection 类的不必要的评论,这绝对无关紧要) 是的,socket_connection 让我感到困惑。 @KirilKirov C 没有范围解析运算符 (::),只有 C++ 有。 @black - 是的,点了。 【参考方案1】: 如果您不需要源地址,在 UDP 套接字上使用 read() 非常好。 如果你connect() UDP 套接字到目的地,你可以使用write()

【讨论】:

"如果您将 UDP 套接字连接到目标,您可以使用 write()。"我们不连接 UDP 套接字,对吧? @AbhishekSagar 错了。您可以将 UDP 套接字连接到目标,在这种情况下,它只向该目标发送和接收。【参考方案2】:

另外,如果我没记错的话(在手册页中找不到),::recv with flags == 0 相当于 ::read (类似于 ::write 和 ::发送)

是的,如果文件描述符是套接字是正确的:send/recv 将失败,否则使用 E​​BADF。 同样,在面向连接的模型中,send 等同于 sendtorecvrecvfrom 与 NULL sockaddr *,因为协议已经提供了它们。

但是,使用 UDP,没有连接,所以这样的调用:

// assume fd to be an UDP socket
write(fd, buff, bytes) 

没有任何意义,因为没有提供目的地 (EDESTADDRREQ)。 相反,当您读取一个数据包时,您就知道它来自哪里,并且您可能希望使用该 IP 以防万一出现问题。

我的建议是:

如果您处于面向连接的模式,例如,请使用 send/recv TCP 使用sendto/recvfrom主要用于无连接通信,例如 UDP 如果您不为原始 I/O 指定任何标志,请使用write/read(上述函数可能被视为更高级别的函数)

我不建议使用一个类来处理这两种协议,而是建议使用两个专门的类;不要混合协议。

【讨论】:

我完全同意这些建议,我也是这么想的,但我很想使用一些非常非常相似(几乎相同)的东西,它已经存在并且已经过多年的测试。 +1,我会再等一下其他 cmets/answers。 您可以将 UDP 套接字连接到目标,在这种情况下您可以使用 send()write()。第三个要点与先前的陈述相矛盾。答案不正确。

以上是关于在 UDP 套接字上使用 write()/read()?的主要内容,如果未能解决你的问题,请参考以下文章

28UDP

TCP,UDP协议下的socket通信

UNIX网络编程笔记—UDP网络编程

linux中read,write和recv,send的区别

当没有可用的目的地时,UDP 套接字的 WSASend 触发 FD_READ

Boost.Asio UDP async_read_from 分段错误