UDP中recvfrom函数与sendto函数分析

一.UDP客户服务器程序的套接字模型

UDP中recvfrom函数与sendto函数分析_第1张图片

与tcp服务器相比较的优缺点:


二、函数解析

#include 
ssize_t recvfrom(int sockfd, void *buf, size_t nbytes,
					int flags, struct sockaddr *from, socklen_t *addrlen);
ssize_t sendto(int sockfd, const void *buf, size_t nsize, 
					int flags, const struct sockaddr *to, const socklen_t *addrlen);
					
			若成功,均返回读或者写的字节数;失败则返回-1 

函数的细节要点分析:

1、recvfrom和sendto的前三个参数与recv和send一模一样。

2、recv中参数from,addrlen都是值-结果参数,from指针指向数据发报者的协议地址的套接字地址结构,而addrlen指针则指向地址结构的字节数返回给调用者(与accept函数的最后俩个参数相似, 返回给调用者,处理完请求后,调用sendto函数)。

3、在recvfrom函数中如果不在乎数据发报者的地址,可必须同时设置from和addrlen参数为NULL。

4、在UDP协议中返回长度为0的数据是可行的。因为在UDP的情况下,他会形成20字节的ip首部(IPv4)和一个8字节的UDP首部而没有数据的IP数据报。所以UDP是无连接。

5、sendto和recvfrom在tcp函数中也是通用的。




三、sendto与recvfrom缓冲分析

send和sendto函数在UDP层没有输出缓冲区,在TCP层有输出缓冲区,recv和recvfrom无论在UDP层还是TCP层都有接收缓冲区。这样看来sendto应该是不会阻塞的。

UDP中recvfrom函数与sendto函数分析_第2张图片

UDP发送缓冲区和接收缓冲区细节分析:

1、这一次我们展示的套接口发送缓冲区用虚框表示,因为它并不存在。UDP套接口有发送缓冲区大小(SO_SNDBUF修改),不过它仅仅是写到套接口的UDP数据报的大小上限。 如果应用程序写一个大于套接口发送缓冲区大小的数据报,内核将返回一个EMSGSIZE错误。 既然UDP不可靠,他不必保存应用进程的数据拷贝,因此无需真正的发送缓冲区(应用进程的数据在沿协议栈往下传递,以某种形式拷贝到内核缓冲区,然而数据链路层在送出数据之后将丢弃该拷贝)

2、UDP没有MSS(最大分节大小)的概念,如果某个UDP应用程序发送大数据,那么他比TCP应用程序更容易分片。从UDP套接口 write成功返回仅仅表示用户写入的数据报或者所有片段已经加入到数据链路层的输出队列。如果该队列没有足够的空间存放该数据报或者他的某个片段,内核 通常返回给应用进程一个ENOBUFS错误(也有的系统不会返回错误)。

3、TCP和UDP都拥有套接口接收缓冲区。TCP套接口接收缓冲区不可能溢出,因为TCP具有流量控制(窗口).然而对于TCP来说, 当接收到的数据报装不进套接口接收缓冲区时,该数据报就丢弃 。UDP是没有流量控制的:较快的发送端可以很容易淹没较慢的接收端,导致接收端的UDP丢弃数据报。

你可能感兴趣的:(unix网络编程)