UDP协议/套接字

每个套接字都有一个发送缓冲区和一个接受缓冲区。

接收缓冲区被TCP、UDP和SCTP用来保存接收到的数据,直到由应用进程来读取。对于TCP来说,套接字接收缓冲区中可用空间的大小限定了TCP通告对端的窗口。TCP套接字接收缓冲区不可能溢出,因为不允许对端发出超过本端所通告窗口大小的数据。这就是TCP的流量控制。如果对端无视窗口大小而发出来了超过该窗口大小的数据,本端TCP将丢弃它们。然而对于UDP来说,当接收到的数据报装不进套接字接收缓冲区时,该数据报就被丢弃掉。回顾一下,UDP是没有流量控制的,较快的发送端可以很容易地淹没较慢的接收端,导致接收端的UDP丢弃数据报。

UDP是无连接不可靠的数据报协议,非常不同于TCP提供的面向连接的可靠字节流。然而相比TCP,有些场合确实更适合使用UDP,使用UDP编写的一些常见应用程序有:DNS、NFS、SNMP。

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


recvfrom函数和sendto函数

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

#include <sys/socket.h>
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, socklen_t addrlen);
钱三个参数sockfd、buff和nbytes等同于read和write函数的三个参数;描述符、指向读入或写出缓冲区的指针和读写字节数。

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

recvfrom的最后两个参数类似于accept的最后两个参数:返回时其中套接字地址结构的内容告诉我们是谁发送了数据报。sendto的最后两个参数类似于connect的最后两个参数:调用时其中套接字地址结构被我们填入数据报将发往的协议地址。

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

写一个0长度字节的数据报是可行的。在UDP情况下,这会形成一个只包含一个IP首部和一个8字节UDP首部而没有数据的IP数据报。这也就意味着对于数据报协议,recvfrom返回0值是可以接受的:它并不想TCP套接字上read返回0值那样表示对端已关闭套接字连接。

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

recvfrom和sendto都可以用于TCP。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值