Unix网络编程-基本UDP套接字编程

在使用TCP编写的应用程序和使用UDP编写的应用程序之间存在一些本质差异,其原因在于这两个传输层之间的差别:UDP是无连接不可靠的数据报协议,非常不同于TCP提供的面向连接的可靠字节流。然而相比TCP,有些场合确实更适合使用UDP。使用UDP编写的一些常见的应用程序有:NDS域名系统、NFS网络文件系统和SNMP简单网络管理协议。

下图给出了典型的UDP客户/服务器程序的函数调用。客户不与服务器建立连接,而是只管使用sendto函数给服务器发送数据报,其中必须指定目的地的地址作为参数。类似的,服务器不接受来自客户的连接,而是只管调用recvfrom函数,等待来自某个客户的数据到达。recvfrom函数将与所接收的数据报一道返回客户的协议地址。因此服务器可以把响应发送给正确的客户。

recvfrom和sendto函数

这两个函数类似于标准的read和write函数,不过需要三个额外的参数。

#include

ssize_t  recvfrom(int  sockfd,  void*  buff , size_t   nbytes , int   flags , struct  sockaddr* from , socklen_t*  addrlen);

ssize_t  sendto(int  sockfd,  const void*  buff, size_t  nbytes, int flags, const  struct  sockaddr* to, socklent_t  addrlen);

                                         返回: 若成功则为读或者写的字节数,若出错则为-1

前三个参数sockfd、buff和nbytes等同于read和write函数的三个参数:描述符、指向读入或者写出缓冲区的指针和读写字节数。

sendto的to参数指向一个含有数据报接收者的协议地址的套接字地址结构,其大小由addrlen参数指定。recvfrom的from参数指向一个将由该函数在返回时填写数据报发送者的协议地址的套接字地址结构,而在该套接字地址结构中填写的字节数则放在addrlen参数所指的整数中返回给调用者。注意,sendto的最后一个参数是一个整数值,而recvfrom的最后一个参数是一个指向整数值的指针。

recvfrom的最后两个参数类似于accept的最后两个参数:返回时其中套接字地址结构的内容告诉我们是谁发送了数据报(UDP情况下)或者是谁发起了连接(TCP情况下)。sendto的最后两个参数类似于connect的最后两个参数:调用时其中套接字地址结构被我们填入数据将发往(UDP情况下)或者与之建立连接(TCP情况下)的协议地址。

这两个函数都把所读写数据的长度作为函数返回值。在recvfrom使用数据报协议的典型用途中,返回值就是所接收数据报中的用户数据量。

写一个长度为0的数据报是可行的。UDP情况下,这会形成一个只包含一个IP首部和一个8字节UDP首部而没有数据的IP数据报。这也意味着对于数据报协议,recvfrom返回0值是可接受的:他并不像TCP套接字上read返回0值那样表示对端已关闭连接。既然UDP是无连接的,因此也就没有诸如关闭一个UDP连接之类的事情。

如果recvfrom的from参数是一个空指针,那么相应大的长度参数(addrlen)也必须是一个NULL指针,表示我们并不关心数据发送者的协议地址。

你可能感兴趣的:(Unix网络编程-基本UDP套接字编程)