网络协议(三)Socket编程之UDP

这篇博客介绍了UDP(User Datagram Protocol)协议的基本特性和应用场景,如DNS、NFS等。讲解了UDP客户-服务器程序中涉及的sendto和recvfrom函数,以及这两个函数与TCP中的connect和accept函数的相似之处。此外,还提到了UDP层的接收缓冲区、无连接不可靠性、潜在的排队现象,以及缺乏流量控制的特点。最后,通过实例说明了UDP服务器通常的并发与迭代行为。
摘要由CSDN通过智能技术生成

UDP(User Datagram Protocol)是无连接不可靠的数据报协议。使用的UDP的常用应用有:DNS、NFS、SNMP、tftp等。

典型的UDP客户-服务器程序


#include <sys/socket.h>

ssize_t sendto(int sockfd, const void *buff, size_t nbytes, int flags,
               const struct sockaddr *addr, socklen_t addrlen);
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

sendto的最后两个参数类似于connect的最后两个参数:调用时其中套接字地址结构被我们填入数据报将发往(UDP)或与之建立连接(TCP)的协议地址。

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

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
recvfrom的最后两个参数类似于accept的最后两个参数:返回时其中套接字地址结构的内容告诉我们是谁发送了数据报(UDP)或是谁发起了连接(TCP)。

(1)UDP层中隐含有排队发生。事实上每个UDP套接字都有一个接收缓冲区,到达该套接字的每个数据报都进入这个套接字接收缓冲区。当进程调用recvfrom时,缓冲区中的下一个数据报以FIFO顺序返回给进程。然而这个缓冲区的大小是有限的。(可以通过SO_RCVBUF进行设置)
(2)知道客户临时端口号的任何进程(无论是与本客户进程相同的主机上还是不同的主机上)都可以向该客户发送数据报,而且这些数据报会与正常的服务器应答混杂。(参见例一)
(3)UDP没有流量控制并且是不可靠的。
一般来说,大多数TCP服务器是并发的,而大多数UDP服务器是迭代的。


例一:

/* 客户端代码 */
#include "../myunp.h"

void UdpClient(int sockfd, const struct sockaddr *pservaddr, socklen_t servlen)
{
	int n = 0;
	char sendline[MAXLINE] = {0};
	char recvline[MAXLINE + 1] = {0};
	socklen_t len = 0;
	struct sockaddr *preplyaddr = NULL;


	while (fgets(sendline, MAXLINE, stdin) != NULL) {
		if (sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen) < 0) {
			printf("sendto error: %s\n", strerror(errno));
			return;
		}

		len = servlen;
		if ((n = recvfrom(sockfd, recvline, MAXLINE, 0, preplyaddr, &len)) < 0) {
			printf("recvfrom error: %s\n", strerror(errno));
			return;
		}
		recvline[n] = 0; /* null terminate */
		
		fputs(recvline, stdout);
	}
}

int main(int argc, char **argv)
{
	int sockfd;
	struct sockaddr_in servaddr;

	if (argc != 2) {
		printf("usage: udpcli <IP address>");
		return -1;
	}

	memset(&servaddr, '\0', sizeof(servaddr));
	servaddr.sin_family 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值