socket 实现udp网络数据通信

利用udp实现网络数据通信

UDP(User Datagram Protocol) 是用户数据报协议,是 OSI 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。它是 IETF RFC 768 是 UDP 的正式规范。UDP 在 IP 数据包的头部仅仅加入了复用和数据完整性校验(数据包检查)的字段。UDP 是对 IP 层的一个简单封装,仅仅在 IP 数据包头部加入了复用(复用)和数据完整性校验(数据包检查)的字段。

UDP 的主要特点包括:

  1. 无连接:UDP 发送数据之前不需要建立连接,因此减少了开销和发送数据之前的时延。
  2. 尽最大努力交付:UDP 不保证可靠交付,也就是说,UDP 协议不保证数据报文能准确地到达目的地,也不保证数据报文的顺序性。
  3. 面向报文:UDP 一次发送一个完整的报文,并在发送报文时保留报文的边界。接收方也是一次接收一个完整的报文。
  4. 没有拥塞控制:UDP 发送方只管发送数据,不确认数据是否到达,因此没有拥塞控制。网络出现拥塞时,UDP 也不会降低发送速率。
  5. 支持一对一、一对多、多对一和多对多的交互通信

UDP客户端的代码(发送端)

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <stdlib.h>
#include <string.h>

// 运行客户端可执行文件   ./xxx  服务器端口  服务器地址

int main(int argc,char *argv[])
{
	//检查参数有效性
	if (argc != 3)
	{
		fprintf(stderr, "argument is invaild ,errno:%d,%s\n",errno,strerror(errno));
		exit(1);
	}

	//1.创建UDP套接字             
	int udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
	if (udp_socket == -1)
	{
		fprintf(stderr, "udp socket error,errno:%d,%s\n",errno,strerror(errno));
		exit(1);
	}

	//2.向目标主机发送消息,需要设置目标端口和目标地址
	char buf[128] = "ok";
	
	struct sockaddr_in  dest_addr;
	dest_addr.sin_family 		= AF_INET; 						//协议族,是固定的
	dest_addr.sin_port   		= htons(atoi(argv[1]));			//服务器端口,必须转换为网络字节序
	dest_addr.sin_addr.s_addr   = inet_addr(argv[2]);			//服务器地址 "192.168.64.xxx"  

	//3.发送客户端的上线时间
	sendto(udp_socket,buf,strlen(buf),0, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
	
	while(1);

	return 0;

}

UDP服务器端的代码(接收端)

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>



int main(int argc,char *argv[])
{
	//检查参数有效性
	if (argc != 3)
	{
		fprintf(stderr, "argument is invaild ,errno:%d,%s\n",errno,strerror(errno));
		exit(1);
	}

	
	//1.创建UDP套接字             
	int udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
	if (udp_socket == -1)
	{
		fprintf(stderr, "udp socket error,errno:%d,%s\n",errno,strerror(errno));
		exit(1);
	}

	//2.需要先绑定服务器的端口和地址
	struct sockaddr_in  host_addr;

	host_addr.sin_family 		= AF_INET; 						//协议族,是固定的
	host_addr.sin_port   		= htons(atoi(argv[1]));			//目标端口,必须转换为网络字节序
	host_addr.sin_addr.s_addr   = inet_addr(INADDR_ANY);		//目标地址 "192.168.64.xxx"  已经转换为网络字节序  INADDR_ANY

	bind(udp_socket,(struct sockaddr *)&host_addr, sizeof(host_addr));

	//3.调用recvfrom等待接收数据,并且接收客户端的网络信息
	char buf[128] = {0};
	struct sockaddr_in  client;
	socklen_t client_len = sizeof(client);
     

	while(1)
	{
		recvfrom(udp_socket,buf,sizeof(buf), 0 ,&client,&client_len); //默认会阻塞
		printf("client ip is [%s],time is [%s]\n",inet_ntoa(client.sin_addr),buf);
		bzero(buf,sizeof(buf));
	}
	
	return 0;

}

在上面的代码中,udp_server.c 创建一个UDP socket,绑定到指定的端口,并等待接收数据。udp_client.c 创建一个UDP socket,并将数据发送到指定的IP地址和端口。

为了运行这些程序,我们需要先编译运行服务器端程序:

gcc udp_server.c -o udp_server  
./udp_server 8888

然后编译运行发送端程序:

gcc udp_client.c -o udp_client
./udp_client 192.168.xxx.xxx

如果代码用法有什么问题,请将问题发至网易邮箱 m17872844806@163.com,作者将及时改正,欢迎与各位老爷交流讨论。

麻烦三连加关注!!!!

比心

posted @ 2024-06-06 20:08  琨为玉也  阅读(62)  评论(0编辑  收藏  举报