UDP信号多个电脑的信息传输测试、配置指南

news/2024/5/18 12:07:59 标签: tcp/ip, udp, 服务器

最近要做一个东西,关于一个软件上得到的信号,如何通过连接的局域网,将数据传输出去。我没做过相关的东西,但是我想应该和软件连接数据库的过程大致是差不多的,就一个ip和一个端口号啥的。

一.问题思路

多个设备同时连接同一个局域网,在一个电脑上发送一个数据,在别的电脑上可以实时接收这个数据。在找工作面试的时候,提前背了相关TCP、UDP的特性,由于TCP是面向连接的,虽然传输数据是可靠的,但是速率是比UDP慢的。因此,我想了想使用UDP传输是比较合适的,这个地方要用到Socket编程。当时面试只是背了背什么C++版本的Socket编程,其大致和java之中的Socket类似,但是还没有用过,趁着这个机会学一下。

二.ip设置与端口的设置

首先,查看本机ip。

按下windows键 + r ,打开运行,输入cmd。

在运行框里输入ipconfig(都是基本操作),查看ip地址。

可以看到我的接收端的ip地址是192.168.1.144.

我现在自己的电脑上进行试一下。

接收端代码:

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <iostream>
#include <WinSock2.h>

#pragma comment(lib, "ws2_32.lib")

int main() {
	// 初始化Winsock
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
		std::cout << "初始化套接字" << std::endl;
		return -1;
	}

	// 创建套接字
	SOCKET receiverSocket = socket(AF_INET, SOCK_DGRAM, 0);
	if (receiverSocket == INVALID_SOCKET) {
		std::cout << "创建套接字失败" << std::endl;
		WSACleanup();
		return -1;
	}

	// 绑定监听地址
	sockaddr_in receiverAddress;
	receiverAddress.sin_family = AF_INET;
	receiverAddress.sin_port = htons(1234);  // 设置监听端口号
	receiverAddress.sin_addr.s_addr = INADDR_ANY;
	if (bind(receiverSocket, (sockaddr*)&receiverAddress, sizeof(receiverAddress)) == SOCKET_ERROR) {
		std::cout << "绑定套接字失败" << std::endl;
		closesocket(receiverSocket);
		WSACleanup();
		return -1;
	}

	// 接收数据
	char buffer[1024];
	sockaddr_in senderAddress;
	int senderAddressSize = sizeof(senderAddress);
	int receivedBytes = recvfrom(receiverSocket, buffer, sizeof(buffer), 0, (sockaddr*)&senderAddress, &senderAddressSize);
	if (receivedBytes == SOCKET_ERROR) {
		std::cout << "接收数据失败" << std::endl;
	}
	else {
		buffer[receivedBytes] = '\0';
		std::cout << "接收到的数据: " << buffer << std::endl;
	}

	// 清理资源
	closesocket(receiverSocket);
	WSACleanup();

	getchar();

	return 0;
}

发送端代码:

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <iostream>
#include <WinSock2.h>

#pragma comment(lib, "ws2_32.lib")

int main() {

	// 初始化Winsock
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
		std::cout << "初始化Socket失败" << std::endl;
		return -1;
	}

	// 创建套接字
	SOCKET senderSocket = socket(AF_INET, SOCK_DGRAM, 0);
	if (senderSocket == INVALID_SOCKET) {
		std::cout << "创建Socket失败" << std::endl;
		WSACleanup();
		return -1;
	}

	// 设置接收方地址
	sockaddr_in receiverAddress;
	receiverAddress.sin_family = AF_INET;
	receiverAddress.sin_port = htons(1234);  // 设置接收方的监听端口号
	receiverAddress.sin_addr.s_addr = inet_addr("192.168.1.144");

	// 发送数据
	const char* message = "你好呀!小杨同学";
	if (sendto(senderSocket, message, strlen(message), 0, (sockaddr*)&receiverAddress, sizeof(receiverAddress)) == SOCKET_ERROR) {
		std::cout << "发送数据失败" << std::endl;
	}
	else {
		std::cout << "成功发送数据" << std::endl;
	}

	// 清理资源
	closesocket(senderSocket);
	WSACleanup();

	return 0;
}

最终的结果,可以看到两台电脑正常通信:

三.问题的出现

一台机器上进行通信是完全没有问题的,但是当两台机器进行通信的时候,其中一台给另外一台发送消息,是正常的,但是当反过来的时候发现通信不了。

我的防火墙已经关闭了,应该没啥问题哈,直接ping一下看看

但是ping了一下发现可以ping通呀。

四.问题的解决

解决方案一:防火墙关闭---端口

接下来去看一下相应的端口状态:使用windows + r,打开任务管理器 -> 性能

性能 -> 打开资源监视器

查看端口的权限情况

可以发现我的监听端口一栏之中,UDP完全是不允许的。

那就继续深究一下端口的问题,发现前面的那个防火墙状态只是用来防病毒的,并不是用来监视端口的。首先打开控制面板

启用或者关闭防火墙

关闭防火墙

发现还是不可以。

查看端口信息,可以看到1235端口并没有指定IPv4。

那么我们需要给1235端口号指定一个IPv4的地址。

这个地方我就直接将端口号改为了本机端口:

发现偶尔可以接收到消息,有的时候还是接收不到消息。

解决方案二:多次传输

想一下UDP的传输协议,这是不可靠的传输协议,因此,重新修改代码,发现与上面那个地址是否绑定无关。

接收端:我将信号变为一直接收的状态

while (1)
	{
		// 接收数据
		char buffer[1024];
		sockaddr_in senderAddress;
		int senderAddressSize = sizeof(senderAddress);
		int receivedBytes = recvfrom(receiverSocket, buffer, sizeof(buffer), 0, (sockaddr*)&senderAddress, &senderAddressSize);
		if (receivedBytes == SOCKET_ERROR) {
			std::cout << "接收数据失败" << std::endl;
		}
		else {
			buffer[receivedBytes] = '\0';
			std::cout << "接收到的数据: " << buffer << std::endl;
		}
	}

发送端:将信号发送10次。

// 发送数据
	const char* message = "你好呀!小杨同学";
	for (int i = 0; i < 10; i++)
	{
		if (sendto(senderSocket, message, strlen(message), 0, (sockaddr*)&receiverAddress, sizeof(receiverAddress)) == SOCKET_ERROR) {
			std::cout << "发送数据失败" << std::endl;
		}
		else {
			std::cout << "成功发送数据" << std::endl;
		}
	}

结果:发送了10次数据,只接收到了八个数据。

通过上述数据说明,在进行使用的过程之中,既然寻求速度选择了UDP发送数据,第一个注意点是需要将防火墙进行关闭。第二个注意点是注意数据的丢失情况,只进行发送一次可能出现发送不成功的问题。

补充解决方案三:方案一的替代版

一般而言,电脑上的防火墙是不允许关闭的,因此,有没有什么更好的方案去替代方案一。

将防火墙进行打开, 防火墙 -> 高级设置

入站规则 -> 新建规则

端口

只允许连接

随便起个名字

可以看到也是正常使用的。


http://www.niftyadmin.cn/n/5288592.html

相关文章

基于 Linux 的批量上传本地 Git 仓库到 Github 的实践

基于 Linux 的批量上传本地 Git 仓库到 Github 的实践 一、需求二、上传本地 Git 仓库2.1 初始版本2.2 优化版本 三、 GitHub 创建空仓库3.1 初始版本3.2 优化版本 一、需求 app目录下的每个文件夹都是一个git仓库&#xff0c;如何使用shell脚本将所有git仓库都上传到github上…

Mini Mybatis-Plus(中)

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 这一篇是用来过渡的&am…

【es6】async、await原理

async、await是es6新出的&#xff0c;主要是为了解决多个promise函数产生的嵌套层级过多的问题。 async、await是基于generator实现的代码中断操作&#xff08;上一个await未处理完时&#xff0c;代码不会继续向下执行&#xff0c;看上去就是中断了代码&#xff09; generator…

【Python】requests库在CTFWeb题中的应用

目录 ①Bugku-GET ②Bugku-POST ③实验吧-天下武功唯快不破 ④Bugku-速度要快 ⑤Bugku-秋名山车神 ⑥Bugku-cookies ①Bugku-GET import requestsresprequests.get(urlhttp://114.67.175.224:12922/,params{what:flag}) print(resp.text)//或者 //resprequests.get(urlht…

怎么实现Servlet的自动加载

在实际开发时&#xff0c;有时候会希望某些Servlet程序可以在Tomcat启动时随即启动。但在默认情况下&#xff0c;第一次访问servlet的时候&#xff0c;才创建servlet对象。 如果servlet构造函数里面的代码或者init方法里面的代码比较多&#xff0c;就会导致用户第一次访问serv…

Node.js版本对比

目录 1. node版本与Npm版本对照表 2. node版本与node-sass版本对照表 3. node-sass与sass-loader版本对照表 1. node版本与Npm版本对照表 以往的版本 | Node.js 下面显示最新的对应内容&#xff0c;如果需要查找历史版本&#xff0c;可以进入上面的页面查询 VersionLTSDateV8np…

【Unity6.0+AI】Unity版的Pytorch之Sentis-把大模型植入Unity

本教程详细讲解什么Sentis。以及恶补一些人工智能神经网络的基础概念,概述了基本流程,加载模型、输入内容到模型、使用GPU让模型推理数据、输出数据。 官方文档 Unity Sentis: Use AI models in Unity Runtime | Unity 主页介绍 官方文档链接:Sentis overview | Sentis | 1…

AR眼镜定制_AR智能硬件方案|显示方案|光学方案

AR眼镜的硬件方案定制是根据客户需求和功能来设计的。从芯片平台选型、主板尺寸大小、内存、电池容量&#xff0c;到实现各项功能的传感器、显示光机模组、摄像头、接口、按键、充电等&#xff0c;再到整机的结构、散热设计&#xff0c;以及双目AR眼镜、单目智能眼镜、全息头盔…