TCP/IP UDP广播无法发送或接收

这篇具有很好参考价值的文章主要介绍了TCP/IP UDP广播无法发送或接收。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

TCP/IP UDP广播无法发送或者接收数据

在看《TCP/IP 网络编程》这本书的时候,看到广播那一节,跟着书上写代码,怎么写都不行,广播就是没法发送/接收,发送端一直在发送数据,接收端就是没有反应。

对了好几遍源码,没有问题。实在是愁人。

最后查了很多资料,确定是网卡的问题。

现在的计算机都是多网卡,至少是有线+无线网卡,如果安装了虚拟机的话,还会有虚拟网卡。

广播地址无法区分网卡,只能按照默认网卡优先级发送,这就导致我们的数据没有走那个我们需要的网卡发送出去。进而导致收不到数据。

解决办法

  1. 禁用一些网卡,将用不到的网卡全部禁用掉
  2. 在代码里添加绑定IP地址的逻辑,绑定到具体的网卡IP

我是用的是第2种方式,比较方便灵活。

发送端Linux源码:

#include <arpa/inet.h>
#include <asm-generic/socket.h>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <iostream>
#include <iterator>
#include <linux/in.h>
#include <sys/endian.h>
#include <sys/socket.h>
#include <unistd.h>

#ifndef FILEPATH
#define FILEPATH "../news.txt"
#endif

constexpr int BUF_SIZE = 30;

int main(int argc, char* argv[])
{
    if (argc != 4) {
        std::cout << "Usage: " << argv[0] << "<Self IP> <Boardcast IP> <PORT>" << std::endl;
        return 0;
    }

    int send_socket = socket(PF_INET, SOCK_DGRAM, 0);

    // 绑定到具体的网卡IP
    sockaddr_in self_adr;
    std::memset(&self_adr, 0, sizeof(self_adr));
    self_adr.sin_family = AF_INET;
    self_adr.sin_addr.s_addr = inet_addr(argv[1]);
    self_adr.sin_port = 0; // 随机分配一个端口
    int res = bind(send_socket, (sockaddr*)&self_adr, sizeof(self_adr));
    if (res == -1) {
        std::cout << "bind error";
    }

    sockaddr_in broad_adr;
    std::memset(&broad_adr, 0, sizeof(broad_adr));
    broad_adr.sin_family = AF_INET;
    broad_adr.sin_addr.s_addr = inet_addr(argv[2]);
    broad_adr.sin_port = htons(std::atoi(argv[3]));

    int so_brd = 1;
    int rtn = setsockopt(send_socket, SOL_SOCKET, SO_BROADCAST, &so_brd, sizeof(so_brd));
    if (rtn == -1) {
        std::cout << "setsockopt error" << std::endl;
        return 0;
    }

    std::ifstream fi { FILEPATH };
    while (!fi.eof()) {
        std::string msg;
        fi >> msg;
        int s = sendto(send_socket, msg.c_str(), msg.size(), 0, (sockaddr*)&broad_adr, sizeof(broad_adr));
        std::cout << s << ":" << msg << std::endl;
        sleep(2);
    }

    close(send_socket);

    return 0;
}


接收端Linux源码:

#include <arpa/inet.h>
#include <cstring>
#include <iostream>
#include <linux/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

constexpr int BUF_SIZE = 30;

int main(int argc, char* argv[])
{
    if (argc != 2) {
        std::cout << "Usage: " << argv[0] << " <PORT>" << std::endl;
        return 0;
    }

    int recv_sock = socket(PF_INET, SOCK_DGRAM, 0);

    sockaddr_in adr;
    std::memset(&adr, 0, sizeof(adr));
    adr.sin_family = AF_INET;
    adr.sin_addr.s_addr = htonl(INADDR_ANY);
    int port = std::atoi(argv[1]);
    adr.sin_port = htons(port);
    std::cout << "PORT: " << port << std::endl;

    int rtn = bind(recv_sock, (sockaddr*)&adr, sizeof(adr));
    if (rtn == -1) {
        std::cout << "bind error" << std::endl;
        return 0;
    }

    char buf[BUF_SIZE] = { 0 };
    while (true) {
        sockaddr_in src_adr;
        socklen_t sl = 0;
        int l = recvfrom(recv_sock, buf, BUF_SIZE - 1, 0, (sockaddr*)&src_adr, &sl);
        std::string srcIp = inet_ntoa(src_adr.sin_addr);
        std::cout << srcIp << " - ";
        if (l < 0) {
            break;
        }
        buf[l] = 0;
        std::cout << buf;
    }

    close(recv_sock);

    return 0;
}


接收端Win源码:文章来源地址https://www.toymoban.com/news/detail-763660.html

#include <WS2tcpip.h>
#include <WinSock2.h>
#include <cstdlib>
#include <cstring>
#include <iostream>

constexpr int BUF_SIZE = 30;

int main(int argc, char* argv[])
{
    if (argc != 2) {
        std::cout << "Usage: " << argv[0] << " <PORT>" << std::endl;
        return 0;
    }

    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        std::cout << "WSA error" << std::endl;
        return 0;
    }

    SOCKET recvSock = socket(PF_INET, SOCK_DGRAM, 0);
    SOCKADDR_IN adr;
    std::memset(&adr, 0, sizeof(adr));
    adr.sin_family = AF_INET;
    adr.sin_addr.s_addr = htonl(INADDR_ANY);
    int port = std::atoi(argv[1]);
    adr.sin_port = htons(port);

    int rtn = bind(recvSock, (SOCKADDR*)&adr, sizeof(adr));
    if (rtn == SOCKET_ERROR) {
        std::cout << "bind error" << std::endl;
        return 0;
    }

    std::cout << "服务已启动:" << port << std::endl;

    char buf[BUF_SIZE] = { 0 };
    while (true) {
        int strLen = recvfrom(recvSock, buf, BUF_SIZE - 1, 0, nullptr, 0);
        if (strLen < 0) {
            break;
        }
        buf[strLen] = 0;
        std::cout << buf << std::endl;
    }

    closesocket(recvSock);
    WSACleanup();

    return 0;
}

到了这里,关于TCP/IP UDP广播无法发送或接收的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java网络编程之IP,端口号,通信协议(UDP,TCP)

    ① C/S :客户端/服务器 在用户本地需要下载安装客户端程序,在远程有一个服务器端程序。 优点:画面精美,用户体验好 缺点:用户需要下载更新 ② B/S :浏览器/服务器 只需要一个浏览器,用户通过指定网址访问对应的服务器。 优点:不需要开发客户端,只需要页面+服务

    2024年02月03日
    浏览(45)
  • 《TCP/IP网络编程》阅读笔记--基于UDP的服务器端/客户端

    目录 1--TCP和UDP的主要区别 2--基于 UDP 的数据 I/O 函数 3--基于 UDP 的回声服务器端/客户端 4--UDP客户端Socket的地址分配 5--UDP存在数据边界 6--UDP已连接与未连接的设置 ① TCP 提供的是可靠数据传输服务,而 UDP 提供的是不可靠数据传输服务; ② UDP 在结构上比 TCP 更简洁,其不会

    2024年02月09日
    浏览(45)
  • C/C++ Socket UDP 广播消息的发送与接收

    局域网内全网段广播消息的IP地址为:255.255.255.255,向该IP地址发送广播消息,局域网下的任何网段的客户机都能收到广播。 对于发送端,如果你只想给某个特定的网段发送消息,例如你的IP地址为192.168.31.107,那么你的广播地址是192.168.31.255,向该广播地址发送广播消息,只

    2024年02月12日
    浏览(28)
  • 网络编程-UDP协议(发送数据和接收数据)

    需要了解TCP协议的,可以看往期文章 https://blog.csdn.net/weixin_43860634/article/details/133274701 通过此图,可以了解UDP所在哪一层级中 发送数据 接收数据 运行效果 1、 UDP是面向无连接通信协议 (通俗一点讲,就是不管是否已连接成功,直接发送数据),该特性正好与TCP协议相反,

    2024年02月07日
    浏览(23)
  • Java netty发送接收(TCP、UDP)

    最下方附项目地址 项目地址 https://gitee.com/xn-mg/netty_kafka

    2024年02月16日
    浏览(29)
  • Linux 下 nc 发送接收 udp、tcp数据

    nc,全名叫 netcat,它可以用来完成很多的网络功能,譬如端口扫描、建立TCP/UDP连接,数据传输、网络调试等等,因此,它也常被称为网络工具的 瑞士军刀 。 一、只服务端使用nc 备注:这种方式只能发送一次数据,不能互相发送 1、udp发送接收数据,udp本质不区分客户端服务

    2024年02月16日
    浏览(28)
  • android开发:获取手机IP和UDP广播

            UDP广播在通讯双方互相不知道对方IP的情况下很有用。这种情形我们也可以用遍历网段来实现,但是比较粗暴,如果网段比较大,不是最多256台主机的C类网段的话,很难做遍历。         UDP广播是解决这种问题的标准方案。         注意,广播和多播是不同的,广

    2024年02月19日
    浏览(27)
  • 生产服务器突然本机无法访问本机IP的端口

            生产服务器突然无法访问自己本机IP地址的端口,通过localhost或者127.0.0.1都可以正常访问         服务器是搭建在虚拟机上面,起初由于服务器内存不足的原因,导致了服务器故障无法连接上,后重启了服务器,由于搭建的应用较多,而且存在应用间互相调用

    2024年02月14日
    浏览(32)
  • 【TCP/IP】广播 - 定义、原理及编程实现

            本文共计2974字,预计阅读时间4分钟 目录 广播 广播的原理及形式 广播的编程与实现 套接字选项设置 发送者 接收者 拓展资料          广播(Broadcast)是指封包在计算机网络中传输时,目的地址为网络中所有设备的一种传输方式。 这里所说的“所有设备”也被

    2024年02月12日
    浏览(20)
  • 《TCP IP网络编程》

            2023.6.28 正式开始学习网络编程。 每一章每一节的笔记都会记录在博客中以便复习。         网络编程又叫套接字编程。所谓网络编程,就是编写程序使两台连网的计算机相互交换数据。 为什么叫套接字编程? 我们平常将插头插入插座上就能从电网中获取电力,同

    2024年02月11日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包