网络编程 ---- UDP

文章目录

  • 前言
  • 一、UDP原理
  • 二、UDP编程步骤
  • 三、代码编写
  • 四、代码结果分析


前言

本文所写代码是基于linux下的编程

一、UDP原理

UDP(UserDatagramProtocol)是一个简单的面向消息的传输层协议,尽管UDP提供标头和有效负载的完整性验证(通过校验和),但它不保证向上层协议提供消息传递,并且UDP层在发送后不会保留UDP 消息的状态。因此,UDP有时被称为不可靠的数据报协议。如果需要传输可靠性,则必须在用户应用程序中实现。
网络编程 ---- UDP_第1张图片
使用UDP传输数据时,由应用程序根据需要提供报文到达确认、排序、流量控制等功能。通常情况下,UDP采用实时传输机制和时间戳来传输语音和视频数据。

二、UDP编程步骤

网络通信三要素: 目的 长度

服务器:
①用socket套接字获取句柄fb = socket(xxx,xxx,xxx)和传参设置相应的通讯模式。
②bind绑定句柄bind(xxx,xxx,xxx),把fb句柄和IP,端口绑定起来。
③使用sendto/recvfrom进行数据的收发。

客服端:
①用socket套接字获取句柄fb = socket(xxx,xxx,xxx)和传参设置相应的通讯模式。
connect(xxx,xxx,xxx)发起连接,需要知道服务器端的ip地址,填充进sockaddr_in结构体里面,发起连接。
③使用send/recv进行数据的收发。

或者

③不使用connect(xxx,xxx,xxx)发起连接,用sendto/recvfrom进行数据的收发。

三、代码编写

server.c

/*具体的函数应该包含什么头文件可以在linux中的man手册查找相应的函数所需要的头文件*/
#include           /* See NOTES */
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


/* socket
 * bind
 * sendto/recvfrom
 */

#define SERVER_PORT 8888

int main(int argc, char **argv)
{
     
	int iSocketServer;
	int iSocketClient;
	struct sockaddr_in tSocketServerAddr;
	struct sockaddr_in tSocketClientAddr;
	int iRet;
	int iAddrLen;

	int iRecvLen;
	unsigned char ucRecvBuf[1000];

	int iClientNum = -1;
	
	iSocketServer = socket(AF_INET, SOCK_DGRAM, 0);
	if (-1 == iSocketServer)
	{
     
		printf("socket error!\n");
		return -1;
	}

	tSocketServerAddr.sin_family      = AF_INET;
	tSocketServerAddr.sin_port        = htons(SERVER_PORT);  /* host to net, short */
 	tSocketServerAddr.sin_addr.s_addr = INADDR_ANY;
	memset(tSocketServerAddr.sin_zero, 0, 8);
	
	iRet = bind(iSocketServer, (const struct sockaddr *)&tSocketServerAddr, sizeof(struct sockaddr));
	if (-1 == iRet)
	{
     
		printf("bind error!\n");
		return -1;
	}


	while (1)
	{
     
		iAddrLen = sizeof(struct sockaddr);
		iRecvLen = recvfrom(iSocketServer, ucRecvBuf, 999, 0, (struct sockaddr *)&tSocketClientAddr, &iAddrLen);
		if (iRecvLen > 0)
		{
     
			ucRecvBuf[iRecvLen] = '\0';
			printf("Get Msg From %s : %s\n", inet_ntoa(tSocketClientAddr.sin_addr), ucRecvBuf);
		}
	}
	
	close(iSocketServer);
	return 0;
}



client.c

#include           /* See NOTES */
#include 
#include 
#include 
#include 
#include 
#include 
#include 

/* socket
 * connect
 * send/recv
 */

#define SERVER_PORT 8888

int main(int argc, char **argv)
{
     
	int iSocketClient;
	struct sockaddr_in tSocketServerAddr;
	
	int iRet;
	unsigned char ucSendBuf[1000];
	int iSendLen;
	int iAddrLen;

	if (argc != 2)
	{
     
		printf("Usage:\n");
		printf("%s \n", argv[0]);
		return -1;
	}

	iSocketClient = socket(AF_INET, SOCK_DGRAM, 0);

	tSocketServerAddr.sin_family      = AF_INET;
	tSocketServerAddr.sin_port        = htons(SERVER_PORT);  /* host to net, short */
 	//tSocketServerAddr.sin_addr.s_addr = INADDR_ANY;
 	if (0 == inet_aton(argv[1], &tSocketServerAddr.sin_addr))
 	{
     
		printf("invalid server_ip\n");
		return -1;
	}
	memset(tSocketServerAddr.sin_zero, 0, 8);

#if 0
	iRet = connect(iSocketClient, (const struct sockaddr *)&tSocketServerAddr, sizeof(struct sockaddr));	
	if (-1 == iRet)
	{
     
		printf("connect error!\n");
		return -1;
	}
#endif

	while (1)
	{
     
		if (fgets(ucSendBuf, 999, stdin))
		{
     
#if 0
			iSendLen = send(iSocketClient, ucSendBuf, strlen(ucSendBuf), 0);
#else
			iAddrLen = sizeof(struct sockaddr);
			iSendLen = sendto(iSocketClient, ucSendBuf, strlen(ucSendBuf), 0,
			                      (const struct sockaddr *)&tSocketServerAddr, iAddrLen);

#endif
			if (iSendLen <= 0)
			{
     
				close(iSocketClient);
				return -1;
			}
		}
	}
	
	return 0;
}


四、代码结果分析

开发板ip: 192.168.1.17
虚拟机ip: 192.168.1.11
网络编程 ---- UDP_第2张图片

开发板作为服务器,虚拟机开启两个客服端与开发板进行通讯。

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