You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++ UDP回环数据包收发失败,请求技术支持

UDP数据包收发实现故障排查请求

我正在按照一篇教程实现C++ UDP数据包收发,但程序无法正常运行。用Wireshark在30001端口捕获回环流量,未发现任何数据包,推测发送环节已失败。已将可执行文件加入防火墙白名单,在MacOS系统下分别用两个终端窗口以sudo ./main receiver或sender模式运行程序(也尝试过不加sudo),暂未实现Windows相关代码。作为网络编程新手,目前陷入困境,恳请帮助。

Main.cpp

#include <iostream>
#include "Socket.h"
#include "Address.h" 

int main(int argc, char* argv[])
{
    if (argc != 2) {
        std::cout << "Usage: " << argv[0] << " [sender|receiver]" << std::endl;
        return 1;
    }
    
    const std::string mode = argv[1];

    if (mode == "sender") 
    {
        int port = 30001;
        Address sendAddress = Address(127, 0, 0, 1, 30000);
        Socket socket;
        if(!socket.Open(port))
        {
            std::cout << "Failed to open socket!" << std::endl;
            return 1;
        }

        const char data[] = "Hello World!";
        if(!socket.Send(sendAddress, data, sizeof(data)))
        {
            std::cout << "Failed to send message!" << std::endl;
        }
    } 
    else if (mode == "receiver") 
    {       
        Socket socket;
        int port = 30000;
        if(!socket.Open(port))
        {
            std::cout << "Failed to open socket!" << std::endl;
            return 1;
        }

        while(true)
        {
            Address sender;
            unsigned char buffer[512];
            int bytes_read = socket.Receive(sender, buffer, sizeof(buffer));
            if(!bytes_read){
                break;
            }

            if(bytes_read > 0)
            {
                std::cout << "Received " << bytes_read << " bytes" << std::endl;
                std::cout << buffer << std::endl;
            }
            else
            {
                std::cout << "." << std::endl;
            }
        }
    } 
    else 
    {
        std::cout << "Invalid mode! Use 'sender' or 'receiver'." << std::endl;
        return 1;
    }
    
    std::cout << "Program closing! Good bye!" << std::endl;    
    return 0; 
}

Socket.cpp

#define PLATFORM_WINDOWS 1
#define PLATFORM_MAC     2
#define PLATFORM_UNIX    3

#if defined(_WIN32)
#define PLATFORM PLATFORM_WINDOWS
#elif defined(__APPLE__)
#define PLATFORM PLATFORM_MAC
#else
#define PLATFORM PLATFORM_UNIX
#endif

#if PLATFORM == PLATFORM_WINDOWS
#include <winsock2.h>

#elif PLATFORM == PLATFORM_MAC || PLATFORM == PLATFORM_UNIX
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <unistd.h>
#endif

#include "Socket.h"
#include "Address.h"
#include <iostream>

Socket::Socket()
{

}

Socket::~Socket()
{
    Close();
}

bool Socket::Open(unsigned short port)
{
    handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

    if (handle <= 0){
        std::cout <<("Failed to create socket")<<std::endl;
        return false;
    }

    sockaddr_in address;
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = htonl(INADDR_ANY);
    address.sin_port = htons((unsigned short) port);

    if(bind(handle, (const sockaddr*) &address, sizeof(sockaddr_in)) < 0)
    {
        std::cout <<("Failed to bind socket")<<std::endl;
        return false;
    }

#if PLATFORM == PLATFORM_MAC || PLATFORM == PLATFORM_UNIX
    int nonBlocking = 1;
    if ( fcntl( handle, F_SETFL, O_NONBLOCK, nonBlocking ) == -1 )
    {
        printf( "failed to set non-blocking\n" );
        return false;
    }
#elif PLATFORM == PLATFORM_WINDOWS
    DWORD nonBlocking = 1;
    if ( ioctlsocket( handle, FIONBIO, &nonBlocking ) != 0 )
    {
        printf( "failed to set non-blocking\n" );
        return false;
    }
#endif

    return true;
}

void Socket::Close()
{
    #if PLATFORM == PLATFORM_MAC || PLATFORM == PLATFORM_UNIX
    close( handle );
    #elif PLATFORM == PLATFORM_WINDOWS
    closesocket( handle );
    #endif
}

bool Socket::Send(const Address& destination, const void* packet_data, int packet_size)
{
    sockaddr_in destAddr;
    destAddr.sin_family = AF_INET;
    destAddr.sin_addr.s_addr = htonl(destination.GetAddress());
    destAddr.sin_port = htons(destination.GetPort());
    
    int sent_bytes = sendto( 
                        handle, 
                        (const char*)packet_data, 
                        packet_size,
                        0, 
                        (sockaddr*)&destAddr, 
                        sizeof(sockaddr_in));

    if(sent_bytes != packet_size )
    {
        printf( "failed to send packet\n" );
        return false;
    }

    std::cout << "Sent " << sent_bytes << " bytes" << std::endl;

    return true;
}

int Socket::Receive(Address& sender, void * data, int size)
{
#if PLATFORM == PLATFORM_WINDOWS    
    typedef int socklen_t;
#endif

    sockaddr_in from;
    socklen_t fromLength = sizeof( from );

    int bytes = recvfrom(handle, 
                        (char*)data, 
                        size,
                        0, 
                        (sockaddr*)&from, 
                        &fromLength );

    if ( bytes <= 0 )
        return bytes;

    unsigned int from_address = ntohl( from.sin_addr.s_addr );
    unsigned int from_port =  ntohs( from.sin_port );
    sender = Address( from_address, from_port );
    return bytes;
}

Address.cpp

#define PLATFORM_WINDOWS 1
#define PLATFORM_MAC     2
#define PLATFORM_UNIX    3

#if defined(_WIN32)
#define PLATFORM PLATFORM_WINDOWS
#elif defined(__APPLE__)
#define PLATFORM PLATFORM_MAC
#else
#define PLATFORM PLATFORM_UNIX
#endif

#if PLATFORM == PLATFORM_WINDOWS
#include <winsock2.h>

#elif PLATFORM == PLATFORM_MAC || PLATFORM == PLATFORM_UNIX
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#endif

#include "Address.h"

Address::Address() : address(0), port(0)
{
}

Address::Address(unsigned char a, unsigned char b, unsigned char c, unsigned char d, unsigned short port)
{
    address = ( a << 24 ) | 
              ( b << 16 ) | 
              ( c << 8  ) | 
                d;
    this->port = port;
}

Address::Address(unsigned int address, unsigned short port)
{
    this->port = port;
    this->address = address;
}

unsigned int Address::GetAddress() const
{
    return address; 
}

unsigned char Address::GetA() const
{
    return ( GetAddress() >> 24 ) & 0xFF;
}

unsigned char Address::GetB() const
{
    return ( GetAddress() >> 16 ) & 0xFF;
}

unsigned char Address::GetC() const
{
    return ( GetAddress() >> 8 ) & 0xFF;
}

unsigned char Address::GetD() const
{
    return GetAddress() & 0xFF;
}

unsigned short Address::GetPort() const
{
    return port;
}

Socket.h

#pragma once

class Socket
{
public:
    Socket();
    ~Socket();

    bool Open(unsigned short port);
    void Close();
    bool IsOpen() const;
    bool Send(const class Address& destination , const void * packet_data, int packet_size);
    int Receive(class Address& sender, void * data, int size);

private:
    int handle;
};

Address.h

#pragma once

class Address
{
public:

    Address();

    Address(unsigned char a, 
            unsigned char b, 
            unsigned char c, 
            unsigned char d, 
            unsigned short port );

    Address(unsigned int address, unsigned short port );

    unsigned int GetAddress() const;

    unsigned char GetA() const;
    unsigned char GetB() const;
    unsigned char GetC() const;
    unsigned char GetD() const;

    unsigned short GetPort() const;

private:

    unsigned int address;
    unsigned short port;
};

内容的提问来源于stack exchange,提问作者Simsalabimson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 19:37:32