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
相关产品推荐
相关产品推荐

