devc++ 使用 winsock 实现 UDP 广播

news/2024/5/18 14:00:55 标签: c++, udp, 开发语言

参考链接

使用UDP发送广播报_udp广播 inaddr_broadcast-CSDN博客

UDP接收端收不到广播的消息问题排查_unity upd广播连接不上是什么情况-CSDN博客

 如何禁用自己电脑的虚拟网卡-百度经验 (baidu.com)

但是wifi 会屏蔽255.255.255.255 广播地址,所以 255.255.255.255 需要借助手机 wifi 路由实现真正局域网内广播,两台电脑连上同一个手机热点后,就可以发消息了。

一般的局域网游戏需要 UDP 广播,然后获取到 IP 才能定向发送消息。

而广播 UDP 的方法和 UDP 定向发送的 方法有些出入,这里是 移植到 DEVC++ 的 UDP 局域网广播方法。

参考第二条连接,在两台电脑连上同一个手机热点后,如果 UDP 还收不到消息:

同一个交换机下 是可以收到广播的 还有就是
电脑的虚拟网卡会拦截广播操作,因为你没有指定一个地址,所以代码正确的情况下,发送不出去或者接收不到,只需要考虑以下两种情况。
1.广播端虚拟网卡没有禁用
2.接收端虚拟网卡没有禁用

PS.虚拟网卡一般是装了虚拟机才会有的。

服务端

// 服务器端
// Server.cpp : Defines the entry point for the console application.
//
#include <WinSock2.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
#pragma warning(disable : 4996)
const int MAX_BUF_LEN = 255;

int main(int argc, CHAR* argv[])
{
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;

	// 启动socket api
	wVersionRequested = MAKEWORD( 2, 2 );
	err = WSAStartup( wVersionRequested, &wsaData );
	if ( err != 0 )
	{
		return -1;
	}

	if ( LOBYTE( wsaData.wVersion ) != 2 ||
	        HIBYTE( wsaData.wVersion ) != 2 )
	{
		WSACleanup( );
		return -1;
	}

	// 创建socket
	SOCKET connect_socket;
	connect_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if(INVALID_SOCKET == connect_socket)
	{
		err = WSAGetLastError();
		printf("/""socket/"" error! error code is %d/n", err);
		return -1;
	}

	SOCKADDR_IN sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(3779);
	sin.sin_addr.s_addr = INADDR_BROADCAST;					// 255.255.255.255 但是会被路由器屏蔽,不过借用手机热点可以广播,只要两个电脑连同一个手机热点就能广播 

	bool bOpt = true;
	//设置该套接字为广播类型
	setsockopt(connect_socket, SOL_SOCKET, SO_BROADCAST, (char*)&bOpt, sizeof(bOpt));

	int nAddrLen = sizeof(SOCKADDR);

	char buff[MAX_BUF_LEN] = "";
	int nLoop = 0;
	while(1)
	{
		nLoop++;
		sprintf(buff, "%8d", nLoop);

		// 发送数据
		int nSendSize = sendto(connect_socket, buff, strlen(buff), 0, (SOCKADDR*)&sin, nAddrLen);
		if(SOCKET_ERROR == nSendSize)
		{
			err = WSAGetLastError();
			printf("/""sendto/"" error!, error code is %d/n", err);
			return -1;
		}
		printf("Send: %s/n", buff);
		Sleep(500);
	}

	return 0;
}

客户端

// 客户端  
// Client.cpp : Defines the entry point for the console application.  
//  
#include <WinSock2.h>  
#include <stdio.h>  
#pragma comment(lib, "ws2_32.lib")  
  #pragma warning(disable : 4996)
const int MAX_BUF_LEN = 255;  
  
int main(int argc, CHAR* argv[])  
{  
    WORD wVersionRequested;  
    WSADATA wsaData;  
    int err;  
  
    // 启动socket api  
    wVersionRequested = MAKEWORD( 2, 2 );  
    err = WSAStartup( wVersionRequested, &wsaData );  
    if ( err != 0 )  
    {  
        return -1;  
    }  
  
    if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 )  
    {  
            WSACleanup( );  
            return -1;   
    }  
  
    // 创建socket  
    SOCKET connect_socket;  
    connect_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);  
    if(INVALID_SOCKET == connect_socket)  
    {  
        err = WSAGetLastError();  
        printf("/""socket/"" error! error code is %d/n", err);  
        return -1;  
    }  
  
    // 用来绑定套接字  
    SOCKADDR_IN sin;  
    sin.sin_family = AF_INET;  
    sin.sin_port = htons(3779);  
    sin.sin_addr.s_addr = 0;  		
  
    // 用来从网络上的广播地址接收数据  
    SOCKADDR_IN sin_from;  
    sin_from.sin_family = AF_INET;  
    sin_from.sin_port = htons(3779);  					// 端口和服务端一致 
    sin_from.sin_addr.s_addr = INADDR_ANY;  			// 接收全部广播 
 	
    //设置该套接字为广播类型,  
    bool bOpt = true;  
    setsockopt(connect_socket, SOL_SOCKET, SO_BROADCAST, (char*)&bOpt, sizeof(bOpt));  
  
    // 绑定套接字  
    err = bind(connect_socket, (SOCKADDR*)&sin, sizeof(SOCKADDR));  
    if(SOCKET_ERROR == err)  
    {  
        err = WSAGetLastError();  
        printf("/""bind/"" error! error code is %d/n", err);  
        return -1;  
    }  
  
    int nAddrLen = sizeof(SOCKADDR);  
    char buff[MAX_BUF_LEN] = "";  

    while(1)  
    {  
        // 接收数据  
        int nSendSize = recvfrom(connect_socket, buff, MAX_BUF_LEN, 0, (SOCKADDR*)&sin_from, &nAddrLen);  
        if(SOCKET_ERROR == nSendSize)  
        {  
            err = WSAGetLastError();  
            printf("/""recvfrom/"" error! error code is %d/n", err);  
            return -1;  
        }  
        buff[nSendSize] = '/0';  
        printf("Recv: %s/n", buff);  
    }  
  
    return 0;  
} 


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

相关文章

2.17学习总结

tarjan 【模板】缩点https://www.luogu.com.cn/problem/P3387 题目描述 给定一个 &#xfffd;n 个点 &#xfffd;m 条边有向图&#xff0c;每个点有一个权值&#xff0c;求一条路径&#xff0c;使路径经过的点权值之和最大。你只需要求出这个权值和。 允许多次经过一条边或者…

解锁Spring Boot中的设计模式—02.解释器模式:探索【解释器模式】的奥秘与应用实践!

解释器模式 1.简介 解释器模式&#xff08;Interpreter Pattern&#xff09;是一种行为设计模式&#xff0c;它用于定义语言的文法&#xff0c;并且解释语言中的表达式。在Java中&#xff0c;解释器模式可以用于构建解释器以解析特定的语言或表达式&#xff0c;如数学表达式、…

【Vue前端】vue使用笔记0基础到高手第2篇:Vue知识点介绍(附代码,已分享)

本系列文章md笔记&#xff08;已分享&#xff09;主要讨论vue相关知识。Vue.js是前端三大新框架&#xff1a;Angular.js、React.js、Vue.js之一&#xff0c;Vue.js目前的使用和关注程度在三大框架中稍微胜出&#xff0c;并且它的热度还在递增。Vue.js是一个轻巧、高性能、可组件…

Code Composer Studio (CCS) - Build All

Code Composer Studio [CCS] - Build All 1. Build AllReferences 1. Build All Project -> Build All (Ctrl B) References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/

Excel TEXT函数格式化日期

一. 基本语法 ⏹Excel 的 TEXT 函数用于将数值或日期格式化为指定的文本格式 TEXT(value, format_text)二. 拼接路径案例 # 将当前单元格日期格式化 "ls -ld /data/jmw/01/"&TEXT(A2,"YYYYMMDD")&""# 此处的日期, 是名称管理器里面定…

【网络安全】什么样的人适合学?该怎么学?

有很多想要转行网络安全或者选择网络安全专业的人在进行决定之前一定会有的问题&#xff1a; 什么样的人适合学习网络安全&#xff1f;我适不适合学习网络安全&#xff1f; 当然&#xff0c;产生这样的疑惑并不奇怪&#xff0c;毕竟网络安全这个专业在2017年才调整为国家一级…

OpenCV识别人脸案例实战

使用级联函数 基本流程 函数介绍 在OpenCV中&#xff0c;人脸检测使用的是cv2.CascadeClassifier.detectMultiScale()函数&#xff0c;它可以检测出图片中所有的人脸。该函数由分类器对象调用&#xff0c;其语法格式为&#xff1a; objects cv2.CascadeClassifier.detectMul…

遥感式路面状况传感器的优势是什么

遥感式路面状况传感器通过其非接触式检测、信息全面准确以及实时性强等特点&#xff0c;为道路维护和管理提供了一个高效、准确的工具。这些优势使得遥感式路面状况传感器在智能交通系统和道路安全管理中发挥着重要作用。【TH-LM2】 遥感式路面状况传感器具有多方面的优势&…