2013-07-18 5 views
0

Моя цель - написать программу на C++, которая получает данные из сети, используя протокол udp. ОС - Linux. У меня мало вопросов.Не удается получить данные из сети, используя протокол udp

  1. Я хочу, чтобы я мог использовать библиотеки linux C для написания программы на C++.
  2. Где-нибудь существует полный учебник, который пошаговый шаг, как программировать с помощью сокетов в Linux? (Я знаю, что в сети много учебников, но я ищу что-то, что помогает мне получать данные udp из INTERNET, а не из другой программы на том же устройстве.).
  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

Извините за беспокойство, проблема была с брандмауэром. –

Смежные вопросы