2013-07-18 55 views
0

我的目标是编写使用udp协议从网络接收数据的C++程序。操作系统 - Linux。我有几个问题。无法使用udp协议从网络接收数据

  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服务器和客户端程序之间的区别吗?

非常感谢。

回答

1

当致电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; 
} 
+0

遗憾的是它不工作... –

+0

很抱歉打扰你,问题是与防火墙。 –