linux网络编程(三)——UDP编程

前一篇文章介绍了linux网络编程中的TCP编程:http://blog.csdn.net/andoubi/article/details/51778988,本文主要介绍UDP编程。

UDP编程模型如下图所示:

linux网络编程(三)——UDP编程_第1张图片

与TCP传输数据相比,UDP传输数据前不需要建立连接。

1、具体用到的函数如下:
服务器端:
创建socket: socket()   绑定地址:bind()  发/收数据:sendto()/recvfrom()  结束连接:close()
客户机端:
创建socket: socket()   发/收数据:sendto()/recvfrom()  结束连接:close()

2、涉及函数详解:

与TCP编程相比,UDP编程知识数据的发送接收函数有变化,其它函数都是一样的。这里就介绍一些数据的发送接收函数。

2.1数据发送函数:sendto函数

linux网络编程(三)——UDP编程_第2张图片

destaddr是接收端套接字的地址。使用sendto函数发送数据,必须指定接收端套接字地址。在TCP编程中,send函数不需要指定地址,因为目标地址暗含在连接中了。

2.2数据接收函数:recvfrom函数

linux网络编程(三)——UDP编程_第3张图片

addr用来存储数据发送端套接字的地址。recvfrom函数在接收数据的同时也获取了发送端套接字地址。而在TCP编程中,是通过accept函数来获取与服务器建立连接的套接字地址。

3、实例(这些代码都是跟着国嵌的视频课程编写的,都是比较简单的功能)
编写一个UDP服务器程序和客户端程序,实现功能是:在客户端通过键盘输入一些字符,这些字符会发送到服务器,并在服务器上打印出来。

服务器端程序:

#include
#include
#include
#include
#include
#include

#define portnum 123//定义一个端口号
#define MSG_SIZE 128

int main()
{
	int sockfd;
	struct sockaddr_in server_addr;
	struct sockaddr_in client_addr;
	char buffer[MSG_SIZE];
	int addr_len , n ;//地址长度
	//1 创建套接字
	if((sockfd=socket( AF_INET, SOCK_DGRAM, 0)) == -1)//如果创建套接字失败
	{
		printf("create socket error!\n");
			exit(1);	
	}
	
	//2.1 初始化地址
	bzero(&server_addr, sizeof(struct sockaddr_in));
	
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons( portnum);//转换成网络字节序
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY );//INADDR_ANY:接收任何消息,转换成网络字节序
	
	//2.2 绑定地址
	bind( sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr) );
	
	//3 接收数据
	while(1)
	{
		addr_len = sizeof(struct sockaddr);
		bzero(buffer, sizeof(buffer));//每次接收前,现将buffer清空
		n = recvfrom(sockfd, buffer, MSG_SIZE, 0,(struct sockaddr *)&client_addr,&addr_len);
		
		//打印出客户机地址
		printf("Receive data from:%s\n", (inet_ntoa(client_addr.sin_addr)) );
		
		buffer[n] = '\0';	
		printf("server receive: %s\n", buffer);
	}
	
	//4 结束连接
	close(sockfd );
	
	return 0 ;
}
客户端程序:(运行程序时,需要指定服务器地址)

#include
#include
#include
#include
#include
#include

#define BUF_SIZE 128
#define PORT 123//端口必须与服务器一样

int main( int argc, char **argv)
{
	
	int sockfd;
	char buffer[BUF_SIZE];
	struct sockaddr_in server_addr;
	
	if(argc!=2)//如果输入的包含命令名称在内的数据 !=2
	{
		printf("Usage: %s  server_ip\n", argv[0]);
		exit(1);	
	}
	
	//1 创建套接字		
	if((sockfd=socket( AF_INET, SOCK_DGRAM, 0)) == -1)//如果创建套接字失败
	{
		printf("create socket error!\n");
			exit(1);	
	}
	
	//服务器地址初始化
	bzero(&server_addr, sizeof(struct sockaddr_in));
	
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons( PORT);//转换成网络字节序
	inet_aton(argv[1],&server_addr.sin_addr);//将键盘输入的字符串格式地址,转化成整型IP
	 
	//2 发送数据
	while(1)
	{
		printf("Please input char:\n");
		fgets( buffer, BUF_SIZE,stdin);
		sendto(sockfd,buffer,strlen(buffer),0,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr));
		bzero(buffer,BUF_SIZE );//每次发送完,将buffer清空
		
	}
	//3关闭连接
	close( sockfd);
}

对比:

TCP协议(传输控制协议)和UDP协议(用户数据报协议)的区别之一是:前者是面向链接的协议,后者是无连接协议。若要使用TCP来传输数据,则传输数据之前,客户端与服务器必须先建立连接。而使用UDP传输数据则不需要建立连接,只需要事先确定数据接收端套接字的地址。相比而言,使用TCP来传输数据要可靠的多。这里有一个简单的比喻来说明TCP和UDP传输数据的差异:

用UDP传输数据相当于给某人邮寄信件。虽然可以邮寄很多信件,但是无法保证信件的投递次序,且在邮递过程中有可能会丢失一些信件。每封信都写有收件人的地址,且没封信可能到达不同的接收者。

用TCP传输数据相当于给某人打电话。首先要通过电话建立一个连接,然后才能彼此双向通信。只有先接通电话才能聊天嘛。建立的每个连接都是端到端的通信通道。会话中不包含地址信息,就像呼叫的两端存在一个点对点的虚拟连接,并且连接本身暗含特定的源和目的地。


参考资料:《UNIX环境高级编程》

前一篇文章:linux网络编程(一)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

转载请注明出处:
作者:Andoubi
原文链接:http://blog.csdn.net/andoubi/article/details/52122748

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