vs2022 c++ 实现UDP聊天室(解释最全)

 一、简介

         udp是面向报文的协议,它不保证消息的完整性,也不为消息提供超时或重发机制。但是,udp的优点是在性能方面比tcp好一些,因为它不建立连接,发送数据和接收数据都只需很少的资源。

二、UDP客户端

        实现原理:该程序使用了C++的socket编程,通过UDP协议在本地和远程服务器之间进行通信。用户可以发送和接收消息。当用户输入'q'时,程序会退出聊天。

#include <Winsock2.h>
#include <iostream>
#include <stdio.h>
#pragma comment (lib, "ws2_32.lib")

int Start_T() {
	//加载套接字库 必须不能省略
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;

	wVersionRequested = MAKEWORD(1, 1);

	err = WSAStartup(wVersionRequested, &wsaData);//错误会返回WSASYSNOTREADY
	if (err != 0)
	{
		return 0;
	}

	if (LOBYTE(wsaData.wVersion) != 1 ||     //低字节为主版本
		HIBYTE(wsaData.wVersion) != 1)      //高字节为副版本
	{
		WSACleanup();
		return 0;
	}

	printf("server is operating!\n\n");

	//创建套接字
	SOCKET sockfd = socket(AF_INET, SOCK_DGRAM, 0);

	//定义一个ipv4存放本地信息
	SOCKADDR_IN myaddr = { 0 };
	myaddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	myaddr.sin_family = AF_INET;
	myaddr.sin_port = htons(5210);

	//定义一个ipv4地址结构存放服务器地址信息
	SOCKADDR_IN ser_addr = { 0 };
	ser_addr.sin_addr.S_un.S_addr = inet_addr("192.168.99.101");
	ser_addr.sin_family = AF_INET;
	ser_addr.sin_port = htons(5210);

	//绑定 
	bind(sockfd, (SOCKADDR*)&myaddr, sizeof(SOCKADDR));


	

	int len = sizeof(SOCKADDR);
	char recvBuf[100];    //收
	char sendBuf[100];    //发
	char tempBuf[100];    //存储中间信息数据
	while (1) {
		//发送
		std::cout << "im client Please input data:" << std::endl;
		std::cin >> sendBuf;
		if ('q' == sendBuf[0])
		{
			sendto(sockfd, "q", strlen("q") + 1, 0, (SOCKADDR*)&ser_addr, len);
			std::cout << "Chat end!";
			break;
		}
		sendto(sockfd, sendBuf, strlen(sendBuf) + 1, 0, (SOCKADDR*)&ser_addr, len);

		//接收
		std::cout << "wait to received" << std::endl;
		int len = recvfrom(sockfd, recvBuf, sizeof(recvBuf), 0, NULL, NULL);
		if ('q' == recvBuf[0])
		{
			sendto(sockfd, "q", strlen("q") + 1, 0, (SOCKADDR*)&ser_addr, len);
			std::cout << "Chat end!";
			break;
		}
		std::cout << recvBuf << std::endl;
	}
	//关闭
	closesocket(sockfd);
	WSACleanup();
	return 0;
}

三、UDP服务器

        这段C++代码实现了一个简单的聊天服务器程序。它的用途是接收客户端的输入,并将其发送回客户端。当客户端输入 'q' 时,聊天服务器结束运行。

        实现原理如下:

  1. 包含必要的头文件,如Windows socket库、iostream和stdio。
  2. 定义一个Start_T函数,用于初始化Windows socket库并创建一个UDP socket。
  3. 创建一个SOCKADDR_IN结构体变量myaddr,用于存储本地IP地址和端口。
  4. 使用socket函数创建一个socket,并使用bind函数绑定到本地地址和端口。
  5. 定义一些变量用于接收和发送数据,如recvBufsendBuftempBuf
  6. 使用recvfrom函数接收客户端的数据,并将其存储在recvBuf中。
  7. 如果接收到 'q',则发送 'q' 回客户端,并退出循环。
  8. 使用sendto函数将数据发送回客户端。
  9. 当客户端发送 'q' 时,聊天服务器结束运行。
  10. 关闭socket并释放资源。
#include <Winsock2.h>
#include <iostream>
#include <stdio.h>
#pragma comment (lib, "ws2_32.lib")

int Start_T() {
	//加载套接字库 必须不能省略
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;

	wVersionRequested = MAKEWORD(1, 1);

	err = WSAStartup(wVersionRequested, &wsaData);//错误会返回WSASYSNOTREADY
	if (err != 0)
	{
		return 0;
	}

	if (LOBYTE(wsaData.wVersion) != 1 ||     //低字节为主版本
		HIBYTE(wsaData.wVersion) != 1)      //高字节为副版本
	{
		WSACleanup();
		return 0;
	}

	printf("server is operating!\n\n");

	//创建套接字
	SOCKET sockfd = socket(AF_INET, SOCK_DGRAM, 0);

	//定义一个ipv4存放本地信息
	SOCKADDR_IN myaddr = { 0 };
	myaddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	myaddr.sin_family = AF_INET;
	myaddr.sin_port = htons(5210);

	//绑定 
	bind(sockfd, (SOCKADDR*)&myaddr, sizeof(SOCKADDR));


	int len = sizeof(SOCKADDR);
	char recvBuf[100] = { 0 };    //收
	char sendBuf[100] = { 0 };    //发
	char tempBuf[100] = { 0 };    //存储中间信息数据

	//来自的地址信息
	SOCKADDR_IN from_addr = { 0 };
	int from_len = sizeof(from_addr);

	while (1) {
		//接收
		std::cout << "wait to received" << std::endl;
		int len = recvfrom(sockfd, recvBuf, sizeof(recvBuf), 0, (SOCKADDR*)&from_addr, &from_len);
		if ('q' == recvBuf[0])
		{
			sendto(sockfd, "q", strlen("q") + 1, 0, (SOCKADDR*)&from_addr, from_len);
			std::cout << "Chat end!";
			break;
		}
		std::cout << recvBuf << std::endl;

		//发送
		std::cout << "im Server Please input data:" << std::endl;
		std::cin >> sendBuf;
		if ('q' == sendBuf[0])
		{
			sendto(sockfd, "q", strlen("q") + 1, 0, (SOCKADDR*)&from_addr, from_len);
			std::cout << "Chat end!";
			break;
		}
		sendto(sockfd, sendBuf, strlen(sendBuf) + 1, 0, (SOCKADDR*)&from_addr, from_len);
	}

	closesocket(sockfd);
	WSACleanup();
}


 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值