【问题标题】:Can't receive data from network using udp protocol无法使用 udp 协议从网络接收数据
【发布时间】:2013-07-18 21:01:27
【问题描述】:

我的目标是编写使用 udp 协议从网络接收数据的 C++ 程序。操作系统-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 服务器和客户端程序的区别?

非常感谢。

【问题讨论】:

    标签: c++ linux udp


    【解决方案1】:

    当调用recvfrom() 时,你传递给它一个指向this-&gt;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;
    }
    

    【讨论】:

    • 很抱歉打扰您,问题出在防火墙上。
    猜你喜欢
    • 1970-01-01
    • 2017-10-17
    • 1970-01-01
    • 2016-06-10
    • 2018-08-24
    • 1970-01-01
    • 2013-11-08
    • 2011-05-13
    • 1970-01-01
    相关资源
    最近更新 更多