LInux UDP编程

在上篇博客中介绍了网络编程中常用的一些函数,和TCP服务器与客户端的程序,这篇博客将介绍TCP与UDP的区别,并用实例程序进行演示。

1、TCP与UDP的区别

TCP向应用层提供可靠的面向连接的数据流传输服务。它能提供高可靠通信(即数据无误、数据无丢失、数据无失序、数据无重复到达)。TCP是面向连接的协议,所谓面向连接,就是当计算机双发通信时必须先建立连接,然后进行数据通信,最后关闭连接,TCP建立连接的过程通常被业内人士称为“三次握手”,(这里不对协议进行详细介绍,有兴趣的读者可以自行百度)

UDP是用户数据协议报,是一种无连接的不可靠传输协议,具有资源消耗小、处理速度快的特点。由于UDP通信之前不需要建立一个连接,因此UDP应用要比TCP应用更加简单。UDP比TCP更为高效,也能更好的解决实时性的问题。目前为止,包括网络视频会议系统在内的众多客户端/服务器模式的网络应用都使用的是UDP。

2、协议的选择

协议的选择应该考虑到数据可靠性、应用的实时性和网络的可靠性。

⑴对数据可靠性要求高的应用需选择TCP,而对数据的可靠性要求不高的应用可选择UDP。

⑵TCP中的三次握手、重传确认等手段可以保证数据传输的可靠性,但使用TCP会有较大的延时,因此不适合对实时性要求较高的应用。而UDP则有很好的实时性。

⑶网络状况不好的情况下需选用TCP(如在广域网等情况),网络状态好的情况下选择UDP可以减少网络负荷。

3、UDP编程实例

/*
server.c
*/

#include <stdio.h>
#include <strings.h>
#include <strings.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <netinet/in.h>


#define BUF_SIZE 128

int main(int argc, char *argv[])
{
	int sockfd, connfd, ret;
	struct sockaddr_in servaddr, cliaddr;
	char buf[BUF_SIZE] = {0};
	socklen_t peerlen;
	
	if(argc < 3)
	{
		printf("Usage:%s <IP> <port>\n", argv[0]);	//提示输入
		exit(-1);
	}
	
	/*建立socket连接*/
	
	if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
	{
		perror("socket");
		exit(-1);
	}
	printf("sockfd = %d\n", sockfd);
	
	/*设置soscket_in结构体中相关参数*/
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(atoi(argv[2]));		//把字符串转换成整型数,然后转换成对应的网络字节序
	servaddr.sin_addr.s_addr = inet_addr(argv[1]);	//sin_addr这个结构体中只有一个元素
	
	/*绑定函数bind(),将socket描述符与本地的Ip与端口绑定*/
	if((ret = bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr))) == -1)
	{
		perror("bind");
		exit(-1);
	}
	printf("bind success\n");
	
	/*调用accept()函数,等待客户端的连接*/
	peerlen = sizeof(cliaddr);
	while(1)
	{
		/*调用recv()函数接收客户端发送的数据*/
		memset(buf, 0, sizeof(buf));
		
//		printf("get in while \n");
		if(recvfrom(sockfd, buf, BUF_SIZE, 0, (struct sockaddr*)&cliaddr, &peerlen) == -1)
		{
			perror("recv");
			exit(-1);
		}
		printf("Receve a message from client: %s", buf);
		memset(buf, 0, sizeof(buf));
		strcpy(buf, "welcome to server\n");
		sendto(sockfd, buf, BUF_SIZE, 0, (struct sockaddr*)&cliaddr, peerlen);
	}
	
	close(sockfd);
	exit(0);	
}
/*
client.c
*/

#include <stdio.h>
#include <strings.h>
#include <strings.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <netinet/in.h>


#define BUF_SIZE 128

int main(int argc, char *argv[])
{
	int sockfd;
	struct sockaddr_in servaddr;
	char buf[BUF_SIZE] = {"hello Server\n"};
	
	if(argc < 3)
	{
		printf("Usage:%s <IP> <port>\n", argv[0]);	//提示执行程序是 传递的参数
		exit(-1);
	}
	
	/*建立socket*/
	
	if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
	{
		perror("socket");
		exit(-1);
	}
	printf("listenfd = %d\n", sockfd);
	
	/*设置soscket_in结构体中相关参数*/
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(atoi(argv[2]));		//把字符串转换成整型数,然后转换成对应的网络字节序
	servaddr.sin_addr.s_addr = inet_addr(argv[1]);	//sin_addr这个结构体中只有一个元素
	
	sendto(sockfd, buf, BUF_SIZE, 0, (struct sockaddr*)&servaddr, sizeof(servaddr));
	/*调用recv()函数接收客户端发送的数据*/
	if(recvfrom(sockfd, buf, BUF_SIZE, 0, NULL, NULL) == -1)
	{
		perror("recv");
		exit(-1);
	}
	printf("Receve a message from server: %s", buf);
	close(sockfd);
	exit(0);	
}

 运行结果如下所示:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值