disaste0_0 2023-11-25 07:46 采纳率: 81.6%
浏览 4
已结题

(未解决)C++的UDP代码在两个不同的VM运行

要求是两个虚拟机的代码之间能够互相通信用的是UDP协议(但是代码经常卡在serevr的recvfrom())
这个图片是设置的IP地址要通过这个来链接

img

这是server虚拟机的IP地址

img

这是client虚拟机的ip地址

img

这是server

#include <iostream>
#include <cstring>
#include <unistd.h>         // For close function
#include <sys/socket.h>
#include <netinet/in.h>     // For sockaddr_in structure

using namespace std; // This allows you to use standard library functions without the 'std::' prefix

int main() {
    // Create server socket
    int ServerSocket;
    ServerSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Create a UDP socket
    if (ServerSocket == -1) {
        cerr << "ERROR: Failed to create ServerSocket" << endl;
        return 1;
    }

    // Configure server address
    sockaddr_in SvrAddr;
    SvrAddr.sin_family = AF_INET;
    SvrAddr.sin_addr.s_addr = INADDR_ANY;
    SvrAddr.sin_port = htons(27000);

    // Bind the socket
    if (bind(ServerSocket, (struct sockaddr *)&SvrAddr, sizeof(SvrAddr)) == -1) {
        close(ServerSocket);
        cerr << "ERROR: Failed to bind ServerSocket" << endl;
        return 1;
    }

    // Buffer for incoming data
    char RxBuffer[128] = {};
    sockaddr_in CltAddr;
    socklen_t addr_len = sizeof(CltAddr);

    // Receive data
    int receivedSize = recvfrom(ServerSocket, RxBuffer, sizeof(RxBuffer), 0, (struct sockaddr*)&CltAddr, &addr_len);

    if (receivedSize < 0) {
        cerr << "ERROR: Failed to receive data" << endl;
        close(ServerSocket);
        return 1;
    } else {
        RxBuffer[receivedSize] = '\0'; // Ensure null-termination
        cout << "Msg Rx: " << RxBuffer << endl;
    }

    // Send a response
    char TxBuffer[128] = "Got It";
    sendto(ServerSocket, TxBuffer, strlen(TxBuffer), 0, (struct sockaddr*)&CltAddr, sizeof(CltAddr));

    // Cleanup
    close(ServerSocket);

    return 0;
}

这是client

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

using namespace std;

int main() {

    // Create a UDP socket
    int ClientSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (ClientSocket < 0) {
        cout << "ERROR: Failed to create Socket" << endl;
        return 1;
    }

    // Specify the server address and port
    struct sockaddr_in SvrAddr;
    memset(&SvrAddr, 0, sizeof(SvrAddr)); // Clear structure
    SvrAddr.sin_family = AF_INET;
    SvrAddr.sin_port = htons(27500); // Server port
    SvrAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // Server IP address

    // Send a message to the server
    const char* sendBuffer = "Hello World";
    ssize_t sendSize = sendto(ClientSocket, sendBuffer, strlen(sendBuffer), 0,
                              (struct sockaddr*)&SvrAddr, sizeof(SvrAddr));
    if (sendSize < 0) {
        cout << "Sending Failed" << endl;
        close(ClientSocket);
        return 1;
    }
    else {
        cout << "Message Successfully Sent: " << sendBuffer << endl;
    }

    // Receive a message from the server
    char recvBuffer[512];
    socklen_t SvrAddrSize = sizeof(SvrAddr);
    ssize_t recvSize = recvfrom(ClientSocket, recvBuffer, sizeof(recvBuffer) - 1, 0,
                                (struct sockaddr*)&SvrAddr, &SvrAddrSize);
    if (recvSize < 0) {
        cout << "Receiving Failed" << endl;
        close(ClientSocket);
        return 1;
    }
    else {
        recvBuffer[recvSize] = '\0'; // Ensure null termination
        cout << "Message Successfully Received: " << recvBuffer << endl;
    }

    // Cleanup: close socket
    close(ClientSocket);

    return 0;
}

  • 写回答

1条回答 默认 最新

  • 呈两面包夹芝士 2023-11-25 08:41
    关注

    引自讯飞星火
    从代码来看,服务器端和客户端的代码都是正确的。但是,如果服务器端的recvfrom()函数卡住,可能是因为没有收到任何数据。你可以尝试在服务器端的recvfrom()函数调用之前添加一个超时设置,以避免无限期地等待数据。

    你可以在创建套接字后,使用setsockopt()函数设置套接字选项。例如,你可以设置SO_RCVTIMEO选项来设置接收超时时间。以下是修改后的服务器端代码:

    // Create server socket
    int ServerSocket;
    ServerSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Create a UDP socket
    if (ServerSocket == -1) {
        cerr << "ERROR: Failed to create ServerSocket" << endl;
        return 1;
    }
    
    // Set receive timeout
    struct timeval timeout;
    timeout.tv_sec = 5; // 5 seconds
    timeout.tv_usec = 0;
    setsockopt(ServerSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
    
    // Configure server address
    sockaddr_in SvrAddr;
    SvrAddr.sin_family = AF_INET;
    SvrAddr.sin_addr.s_addr = INADDR_ANY;
    SvrAddr.sin_port = htons(27000);
    
    // Bind the socket
    if (bind(ServerSocket, (struct sockaddr *)&SvrAddr, sizeof(SvrAddr)) == -1) {
        close(ServerSocket);
        cerr << "ERROR: Failed to bind ServerSocket" << endl;
        return 1;
    }
    
    // ... (rest of the code remains unchanged)
    

    这样,如果在5秒内没有收到任何数据,recvfrom()函数将返回一个错误,而不是无限期地等待。你可以根据需要调整超时时间。

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 11月25日
  • 修改了问题 11月25日
  • 创建了问题 11月25日

悬赏问题

  • ¥30 电脑误删了手机的照片怎么恢复?
  • ¥15 (标签-python|关键词-char)
  • ¥15 python+selenium,在新增时弹出了一个输入框
  • ¥15 苹果验机结果的api接口哪里有??单次调用1毛钱及以下。
  • ¥20 学生成绩管理系统设计
  • ¥15 来一个cc穿盾脚本开发者
  • ¥15 CST2023安装报错
  • ¥15 使用diffusionbert生成文字 结果是PAD和UNK怎么办
  • ¥15 有人懂怎么做大模型的客服系统吗?卡住了卡住了
  • ¥20 firefly-rk3399上启动卡住了