无法使用 udp 协议从网络接收数据

Can't receive data from network using udp protocol

本文关键字:网络 数据 协议 udp      更新时间:2023-10-16

我的目标是编写C++程序,该程序使用udp协议从网络接收数据。操作系统-linux。我没有什么问题。

  1. 我想确保我可以使用linux C库来编写C++程序
  2. 有没有完整的教程可以一步一步地展示如何在linux中使用套接字进行编程?(我知道网络上有很多教程,但我正在寻找一些东西,帮助我从INTERNET接收udp数据,而不是从同一设备上的另一个程序。)
  3. 我在终端(使用tcpdump)中看到我的计算机接收到寻址到指定端口的udp包。我的程序看起来像这个有什么问题

    class Connection
    {
    private:
        char * buffer;
        int bufferSize;
        int sock;
        struct sockaddr_in server;
        struct sockaddr_in other;
        socklen_t addressLength;
    public:
        Connection(string address, int port, int bufferSize);
        ~Connection();
        int reciveData();
    };
    Connection::Connection(string address, int port, int bufferSize)
    {
        this->addressLength = sizeof(this->server);
        this->sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
        if(this->sock == -1)
        {
            cout << "Socket error!" << endl;
            exit(1);
        }
        memset(&(this->server), 0, sizeof(this->server));
        this->server.sin_family = AF_INET;
        this->server.sin_port = htons(port);
        this->server.sin_addr.s_addr = htonl(INADDR_ANY);
        if( bind(this->sock, (sockaddr *) &(this->server), this->addressLength) == -1 )
        {
            cout << "Bind socket error!" << endl;
            exit(1);
        }
        this->bufferSize = bufferSize;
        this->buffer = new char[bufferSize];
        cout << "Socket created!" << endl;
    }
    int Connection::receiveData()
    {
        int returned;
        fflush(stdout);
        if( (returned =recvfrom(this->sock, this->buffer, this->bufferSize, 0, (sockaddr *) &(this->other), &this->addressLength)) == -1)
        {
            cout << "Receiving error!" << endl;
            exit(1);
        }
        return returned;
    }
    

    当我调用receiveData()时,什么都没有发生——我想程序正在等待某个udp包(我不知道他为什么没有收到它)。

  4. 有人能解释一下udp服务器和客户端程序之间的区别吗?

非常感谢。

调用recvfrom()时,您正在向它传递一个指向this->addressLength的指针。在输入时,长度需要是地址缓冲区的完整大小。输出时,返回实际地址长度。因此,recvfrom()可能正在更改您的addressLength成员,从而影响后续代码。请使用本地变量:

int Connection::receiveData()
{
    int returned;
    int addrlen = sizeof(this->other);
    fflush(stdout);
    returned = recvfrom(this->sock, this->buffer, this->bufferSize, 0, (sockaddr *) &(this->other), &addrLen);
    if( returned == -1 )
    {
        cout << "Receiving error!" << endl;
        exit(1);
    }
    return returned;
}

或者,使用单独的成员变量:

class Connection
{
private:
    char * buffer;
    int bufferSize;
    int sock;
    struct sockaddr_in server;
    struct sockaddr_in other;
    socklen_t serverAddressLength;
    socklen_t otherAddressLength;
public:
    Connection(string address, int port, int bufferSize);
    ~Connection();
    int reciveData();
};

Connection::Connection(string address, int port, int bufferSize)
{
    this->serverAddressLength = sizeof(this->server);
    this->sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if(this->sock == -1)
    {
        cout << "Socket error!" << endl;
        exit(1);
    }
    if(this->sock == -1)
    {
        cout << "Socket error!" << endl;
        exit(1);
    }
    memset(&(this->server), 0, sizeof(this->server));
    this->server.sin_family = AF_INET;
    this->server.sin_port = htons(port);
    this->server.sin_addr.s_addr = htonl(INADDR_ANY);
    if( bind(this->sock, (sockaddr *) &(this->server), this->serverAddressLength) == -1 )
    {
        cout << "Bind socket error!" << endl;
        exit(1);
    }
    this->bufferSize = bufferSize;
    this->buffer = new char[bufferSize];
    cout << "Socket created!" << endl;
}
int Connection::receiveData()
{
    int returned;
    fflush(stdout);
    this->otherAddressLength = sizeof(this->other);
    if( (returned =recvfrom(this->sock, this->buffer, this->bufferSize, 0, (sockaddr *) &(this->other), &this->otherAddressLength)) == -1)
    {
        cout << "Receiving error!" << endl;
        exit(1);
    }
    return returned;
}