UDP和TCP区别



一、协议区别

UDP协议

            面向无连接(如发邮件,不用通知对方,直接发出去,至于对方有没有收到就不管了)的用户数据报协议,在传输数前

      不需要先建立连接;目地主机的运输层收到UDP报文后,不需要给出任何确认

      1.相比TCP速度稍快些;

      2.编程简单,占用系统资源低;

      3.支持广播和多播,可以一对一,一对多,多对一和多对多的交互通信;

      4.UDP首部只需8个字节;

      5.UDP应用:拥有大量client,对数据安全性无特殊要求,网络负担非常重,但对相应速度要求高。比如:DNS(域名解析)、

         NFS(网络文件系统)、RTP(流媒体)等.

TCP协议

            面向连接(如打电话要先拨号建立连接,拨通之后才可以说话)的流式协议;可靠、有序、出错重传、且每收到一个数据都

      要给出相应的确认

      1.不支持广播和多播,每条TCP连接只能是点到点;

      2.建立连接时需要三次握手,断开连接时需要四次挥手;

      3.TCP首部需要20字节;

      4.TCP应用:对网络通信质量有要求,整个数据要求准确无误时。比如:HTTP、HTTPS、FTP等传输文件的协议,POP、

         SMTP等邮件传输协议.

二、编程区别

      UDP服务端编程步骤:

          1.创建一个socket,用函数socket();

          2.绑定IP地址、端口等信息到socket上,用函数bind();

          3.循环接收数据,用函数recvfrom();

          4.关闭网络连接。

          5.代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
	unsigned short port = 8008;
	int sockfd = socket(AF_INET, SOCK_DGRAM, 0);  //创建UDP套接字
	if(sockfd < 0)
	{
		perror("socket");
		exit(-1);
	}
		
	struct sockaddr_in my_addr;  //定义本地信息结构体
	bzero(&my_addr, sizeof(my_addr));
	my_addr.sin_family = AF_INET;
	my_addr.sin_port   = htons(port);
	my_addr.sin_addr.s_addr = htonl(INADDR_ANY); //htonl()将32位主机字节序数据转换成网络字节序数据
	
	printf("Binding server to port %d\n", port);
	int err_log = bind(sockfd, (struct sockaddr*)&my_addr, sizeof(my_addr));  //绑定本地信息(IP、端口号)
	if(err_log != 0)
	{
		perror("bind");
		close(sockfd);		
		exit(-1);
	}
	printf("receive data...\n");
	while(1)
	{
		int recv_len;
		char recv_buf[512] = "";
		struct sockaddr_in client_addr; //定义接收客户端信息结构体
		char cli_ip[INET_ADDRSTRLEN] = "";//INET_ADDRSTRLEN=16
		socklen_t cliaddr_len = sizeof(client_addr);
		
		recv_len = recvfrom(sockfd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr*)&client_addr, &cliaddr_len);  //接收数据
		inet_ntop(AF_INET, &client_addr.sin_addr, cli_ip, INET_ADDRSTRLEN); //将32位无符号整数转换成点分十进制数串
		printf("\nip:%s ,port:%d\n",cli_ip, ntohs(client_addr.sin_port));
		printf("data(%d):%s\n",recv_len,recv_buf);
	}
	close(sockfd);
	return 0;
}

      UDP客户端编程步骤:

          1.创建一个socket,用函数socket();

          2.发送数据,用函数sendto();

          3.关闭网络连接。

          4.代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
	unsigned short port = 8008;
	char *server_ip = "192.168.1.2";
	int sockfd = socket(AF_INET, SOCK_DGRAM, 0);    	//创建UDP套接字
	if(sockfd < 0)
	{
		perror("socket");
		exit(-1);
	}
	
	struct sockaddr_in dest_addr; //定义服务器信息结构体
	bzero(&dest_addr, sizeof(dest_addr));
	dest_addr.sin_family = AF_INET;
	dest_addr.sin_port   = htons(port);
	inet_pton(AF_INET, server_ip, &dest_addr.sin_addr);

	printf("send data to UDP server %s:%d!\n", server_ip, port);
	
	while(1)
	{
		char send_buf[512] = "";
		fgets(send_buf, sizeof(send_buf), stdin);//获取输入
		send_buf[strlen(send_buf)-1] = '\0';
		sendto(sockfd, send_buf, strlen(send_buf), 0, (struct sockaddr*)&dest_addr, sizeof(dest_addr));//发送数据
	}
	
	close(sockfd);
	return 0;
}

      TCP服务端编程步骤:

          1.创建一个socket,用函数socket();

          2.绑定IP地址、端口等信息到socket上,用函数bind();

          3.开启监听,用函数listen();

          4.接收客户端上来的连接,用函数accept();

          5.收发数据,用函数send()和recv(),或者read()和write();

          6.关闭网络连接;

          7.关闭监听。

          8.代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>						
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>				
int main(int argc, char *argv[])
{
	unsigned short port = 8008;			
	struct sockaddr_in my_addr;  //定义本地信息结构体
	bzero(&my_addr, sizeof(my_addr));	     
	my_addr.sin_family = AF_INET;
	my_addr.sin_port   = htons(port);
	my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	
	int err_log = bind(sockfd, (struct sockaddr*)&my_addr, sizeof(my_addr));
	if( err_log != 0)
	{
		perror("binding");
		close(sockfd);		
		exit(-1);
	}
	
	err_log = listen(sockfd, 10);
	if(err_log != 0)
	{
		perror("listen");
		close(sockfd);		
		exit(-1);
	}	
	
	printf("listen client @port=%d...\n",port);

	while(1)
	{	
	
		struct sockaddr_in client_addr;	//定义接收客户端信息结构体	   
		char cli_ip[INET_ADDRSTRLEN] = "";	   
		socklen_t cliaddr_len = sizeof(client_addr);    
		
		int connfd;
		connfd = accept(sockfd, (struct sockaddr*)&client_addr, &cliaddr_len);       
		if(connfd < 0)
		{
			perror("accept");
			continue;
		}

		inet_ntop(AF_INET, &client_addr.sin_addr, cli_ip, INET_ADDRSTRLEN);
		printf("client ip=%s,port=%d\n", cli_ip,ntohs(client_addr.sin_port));
		
		char recv_buf[2048] = "";
		while( recv(connfd, recv_buf, sizeof(recv_buf), 0) > 0 ) //接收数据
		{
			printf("\nrecv data:\n");
			printf("%s\n",recv_buf);
		}
		
		close(connfd);     //关闭已连接套接字
		printf("client closed!\n");
	}
	close(sockfd);         //关闭监听套接字
	return 0;
}

      TCP客户端编程步骤:

         1.创建一个socket,用函数socket();  

         2.连接服务器,用函数connect();

         3.收发数据,用函数send()和recv(),或者read()和write();

         4.关闭网络连接。

         5.代码

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc, char *argv[])
{
	unsigned short port = 8008;        // 服务器的端口号
	char *server_ip = "192.168.1.2";   // 服务器ip地址

	int sockfd = socket(AF_INET, SOCK_STREAM, 0);// 创建TCP套接字
	if(sockfd < 0)
	{
		perror("socket");
		exit(-1);
	}
	
	struct sockaddr_in server_addr; //定义服务器信息结构体
	bzero(&server_addr,sizeof(server_addr)); 
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(port);
	inet_pton(AF_INET, server_ip, &server_addr.sin_addr);
	
	int err_log = connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));      // 主动连接服务器
	if(err_log != 0)
	{
		perror("connect");
		close(sockfd);
		exit(-1);
	}
	
	char send_buf[512] = "";
	printf("send data to %s:%d\n",server_ip,port);
	while(1)
	{
		printf("send:");
		fgets(send_buf,sizeof(send_buf),stdin);
		send_buf[strlen(send_buf)-1]='\0';
		send(sockfd, send_buf, strlen(send_buf), 0);   // 向服务器发送信息
	}

	close(sockfd);
	return 0;
}

      C/S架构图:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值