网络编程之UDP初级实现

该博客展示了如何使用C++实现基于UDP的服务器和客户端通信。服务器监听特定端口,接收并回应客户端的消息,而客户端发送消息到服务器并接收响应。主要涉及WinSock2库的使用,包括socket创建、bind、sendto和recvfrom等函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

服务端:

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <iostream>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib")
using namespace  std;

int main()
{
	WSADATA wsaData;
	int ret = 0;
	if ((ret = WSAStartup(MAKEWORD(2,2),&wsaData)) != 0)
	{
		return -1;
	}
	// AF_INET 表示采用TCP/IP协议族
	// SOCK_STREAM 表示采用TCP协议
	// 0是通常的默认情况
	SOCKET InSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

	SOCKADDR_IN Addr;
	Addr.sin_addr.S_un.S_addr = INADDR_ANY; //inet_addr("0.0.0.0"); 
	Addr.sin_family = AF_INET; //AF_INET 表示采用TCP/IP协议族    当sockaddr_in.sin_family = AF_INET时,sockaddr = sockaddr_in。
	Addr.sin_port = htons(12345);// socket对应的端口

	// 将socket绑定到某个IP和端口(IP标识主机,端口标识通信进程)
	bind(InSocket, (SOCKADDR *)&Addr, sizeof(SOCKADDR));

	SOCKADDR_IN AddrClient;  //&addrClient是缓冲区地址,保存了客户端的IP和端口等信息
	int ClientAddrLen = sizeof(SOCKADDR_IN); //len是包含地址信息的长度
	while (1)
	{
		char RecvBuff[1024] = { 0 };
		recvfrom(InSocket, RecvBuff, 1024, 0, (SOCKADDR *)&AddrClient, &ClientAddrLen);

		printf("端口是%d  ", ntohs(AddrClient.sin_port));//ntohs 将网络字节序转为主机字节序
		printf("IP是%s  ", inet_ntoa(AddrClient.sin_addr));//IP  net_ntoa 函数转换网络字节排序的地址为标准的ASCII以点分开的地址
		printf("数据是%s\n", RecvBuff);

		memset(RecvBuff, 0, 1024);
		sprintf_s(RecvBuff, 1024, "你好,客户端!我是服务器");
		sendto(InSocket, RecvBuff, strlen(RecvBuff), 0, (SOCKADDR*)&AddrClient, sizeof(SOCKADDR));
	}

	//关闭
	closesocket(InSocket);
	WSACleanup();
	getchar();
	return 0;
}


客户端

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <WinSock2.h>
#include <iostream>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib")
using namespace  std;

int main()
{
	WSADATA wsaData;
	int ret = 0;
	if ((ret = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0)
	{
		return -1;
	}

	SOCKET Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	//以广播的形式
	//BOOL optval = TRUE;
	//setsockopt(InSocket, SOL_SOCKET, SO_BROADCAST | SO_REUSEADDR, (char *)&optval, optval);

	//发送端IP和端口
	SOCKADDR_IN Addr;
	Addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	Addr.sin_family = AF_INET; //主机字节序
	Addr.sin_port = htons(54321);//将主机字节序变为网络字节序
	
	while (1)
	{
		sendto(Socket, "你好,服务器!我是客户端", strlen("你好,服务器!我是客户端"), 0, (SOCKADDR*)&Addr, sizeof(SOCKADDR));
		int len = sizeof(SOCKADDR);
		char buffer[1024] = { 0 };
		recvfrom(Socket, buffer, 1024, 0, (SOCKADDR*)&Addr, &len);
		printf("目标端口是%d  ", ntohs(Addr.sin_port));//ntohs 将网络字节序转为主机字节序
		printf("目标IP是%s  ", inet_ntoa(Addr.sin_addr));//IP  net_ntoa 函数转换网络字节排序的地址为标准的ASCII以点分开的地址
		printf("数据:%s\n",buffer);
	}
	
	//关闭
	closesocket(Socket);
	WSACleanup();
	getchar();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值