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

Kir*_*rov 7 c c++ sockets linux udp

根据手册页:

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()相同.

另外,如果我没有错(不能在手册页找到它),recv与flags == 0相当于read(模拟到write和send).


所以:

  • 这是否意味着,read在UDP套接字上使用是完全正常的(如果我不需要src_addr)?
  • 有没有办法write在UDP套接字上使用(现在我在sendto's dest_addr参数中设置目标地址)?

use*_*421 5

  • 使用read()一个UDP套接字是完全正常的,如果你不需要的源地址.
  • write()如果connect()UDP套接字到目的地,则可以使用.


edm*_*dmz 2

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

是的,如果文件描述符是套接字,则正确:send/recv否则 EBADF 将失败。
在面向连接的模型中,这也确实send相当于sendto和recv与recvfromNULL sockaddr *,因为协议已经提供了它们。

然而,对于 UDP,没有连接,因此调用如下:

// assume fd to be an UDP socket
write(fd, buff, bytes) 
Run Code Online (Sandbox Code Playgroud)

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

我的建议是:

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

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