• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

网络通讯学习3-----UDP通讯(仅)

武飞扬头像
你像寒风和烈酒。
帮助2

理论

UDP(用户数据报协议)是一个无连接,不可靠的数据传输,其特点是简单,快捷。相比与TCP,UDP不需要建立连接(不需connect、accept函数),数据发送接收之后,不需要终止连接。基于UDP的程序,避免了TCP运行的开销,在效率与速度上具有更好的表现。UDP是无连接的,可能会有数据的丢失,延迟,这些需要应用程序自己处理。

编码

重要函数:

int recvfrom(SOCKET s, char *buf, int len, int flags, struct sockaddr *from, int *fromlen );

第一个参数: socket为对方的socket。

第二个参数: 接收数据的缓冲区。

第三个参数: 数据缓冲区大小。

第四个参数: 紧急状态,一般这为0。

第五个参数: 可选,对应AF_INET,返回对方IP,端口等socket地址标识sockaddr_in。

第六个参数: 可选,对应AF_INET,使用sockaddr_in结构大小。

该函数用于UDP接收数据。

返回值:如果未发生错误,则 recvfrom 将返回收到的字节数。如果连接已正常关闭,则返回值为零。否则,将返回值 SOCKET_ERROR,并且可以通过调用 WSAGetLastError 来检索特定的错误代码。

int sendto(SOCKET s, const char *buf, int len, int flags, const struct sockaddr *to, int tolen);

第一个参数: socket为对方的socket。

第二个参数: 发送数据的缓冲区。

第三个参数: 数据缓冲区大小。

第四个参数: 紧急状态,一般这为0。

第五个参数: 可选,对应AF_INET,对方IP,端口等socket地址标识sockaddr_in。

第六个参数: 可选,对应AF_INET,使用sockaddr_in结构大小。

该函数用于UDP发送数据。

  • 服务端
#include <stdio.h>
#include <WinSock2.h>
#include <time.h>
#pragma comment (lib, "ws2_32.lib")  //加载 ws2_32.lib
#pragma warning(disable:4996)  //解决C4996 'inet_addr'错误

int main()
{
	//1、初始化WS2_32.DLL
	WSADATA wsa;
	WSAStartup(WINSOCK_VERSION, &wsa);

	SOCKET serversoc;
	SOCKET clientsoc;
	SOCKADDR_IN serveraddr;
	SOCKADDR_IN clientaddr;
	int client_len = sizeof(clientaddr);
	int server_len = sizeof(serveraddr);
	char* Send_data;
	int Send_len;
	char Recv_buf[64];
	int result;
	time_t nowtime;

	//命名协议,IP,端口
	serveraddr.sin_family = AF_INET;
	serveraddr.sin_port = htons(9000);
	serveraddr.sin_addr.s_addr = INADDR_ANY;

	//2、创建服务端socket,
	serversoc = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);//或不指定IPPROTO_UDP,直接使用0


	//3、绑定socket,即socket和IP地址及端口号绑定
	result = bind(serversoc, (SOCKADDR*)&serveraddr, server_len);
	if (result == SOCKET_ERROR)
	{
		printf("套接字绑定失败!\n");
		closesocket(serversoc);
		return -1;
	}

	printf("Server is running.....\n");
	//4、创建客户端的socket,用于发送数据,不关注客户端信息,因为接收的时候,这些信息已经存放到结构体中了
	clientsoc = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	while (1)
	{
		//5、接收数据,数据写入接收缓存,客户端信息写入接收数据结构
		result = recvfrom(serversoc, Recv_buf, 64, 0, (SOCKADDR*)&clientaddr, &client_len);
		if (result >= 0)
		{
			Recv_buf[result] = 0;
			printf("接收数据为:  %s \n", Recv_buf);

			//6、发送回复数据
			nowtime = time(0);
			Send_data = ctime(&nowtime);
			Send_len = strlen(Send_data);
			result = sendto(clientsoc, Send_data, Send_len, 0, (SOCKADDR*)&clientaddr, sizeof(clientaddr));
			printf("Server is running.....\n");
		}
	}
	//7、关闭socket
	closesocket(serversoc);
	//8、关闭DLL
	WSACleanup();
	return 0;
}
学新通
  • 客户端
#include <stdio.h>
#include <WinSock2.h>
#pragma comment (lib, "ws2_32.lib")  //加载 ws2_32.lib
#pragma warning(disable:4996)  //解决C4996 'inet_addr'错误

int main()
{
	WSADATA wsa;
	SOCKET serversoc;
	/*保存请求的服务端IP地址和端口设置信息*/
	SOCKADDR_IN serveraddr;
	/*保存接收过来的关于服务端的IP地址和端口信息*/
	SOCKADDR_IN peeraddr;
	int peer_len = sizeof(peeraddr);
	/*接收数据缓存*/
	char Recv_buf[64];
	char* Send_data = "Hello,server!";
	int Send_len = strlen(Send_data);
	int time_out = 2000;    //接收超时
	int result;
	//1、初始化WS2_32.DLL
	//define WINSOCK_VERSION MAKEWORD(2, 2)-------2.2版本
	WSAStartup(WINSOCK_VERSION, &wsa);

	//设置服务端信息:协议簇,IP,端口
	serveraddr.sin_family = AF_INET;
	serveraddr.sin_port = htons(9000);
	serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");

	if (serveraddr.sin_addr.s_addr == INADDR_NONE)
	{
		printf("不可用地址!\n");
		return -1;
	}

	//2、创建服务端套接字,注意,该套接字发送数据时候要设置服务端IP地址和端口,接收则不需要
	serversoc = socket(AF_INET, SOCK_DGRAM, 0);

	result = setsockopt(serversoc, SOL_SOCKET, SO_RCVTIMEO, (char*)&time_out, sizeof(time_out));
	for (int i = 0; i < 3; i  )
	{
		//3、发送数据
		result = sendto(serversoc, Send_data, Send_len, 0, (SOCKADDR*)&serveraddr, sizeof(serveraddr));

		//4、接收数据
		result = recvfrom(serversoc, Recv_buf, 64, 0, (SOCKADDR*)&peeraddr, &peer_len);
		if (result >= 0)
		{
			Recv_buf[result] = 0;
			printf("接收数据为:  %s \n", Recv_buf);
		}
	}
	closesocket(serversoc);
	WSACleanup();
	getchar();
	return 0;
}
学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgbeeka
系列文章
更多 icon
同类精品
更多 icon
继续加载