2013-04-20 2 views
1

Я работаю над еще одной библиотекой сокетов для Linux на C++, а также для личного упражнения. Вот мой код: «это это когда-либо называли»C++ - Функция возвращает, но не передает управление

#ifndef SOCKET_H 
#define SOCKET_H 

#include <sys/types.h> 
#include <sys/socket.h> 
#include <netdb.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <iostream> 
using namespace std; 

/** 
* Creates a struct to hold all the necessary information to create a socket.<br/> 
* Typically, you should not need to call this yourself, as it is done when you  call   listen() or dial() 
* @param host The hostname or IP address to connect to. 
* @param service The service on that machine (e.g "http" or "80") 
* @param sock The type of socket ("tcp" or "udp") 
* @return A addrinfo struct with all the required information to create a connection. 
*/ 
addrinfo setup(const char *host,const char *service,const char *sock) { 
    struct addrinfo hints; 
    struct addrinfo *serv; 
cout << "2.call to setup()\n"; 
//cout << "3.setup() returns here.\n"; 
//return *serv; 
    int status=0; 
/*struct addrinfo hints; 
    struct addrinfo *serv;*/ 

    memset(&hints,0,sizeof hints); 
    hints.ai_family=AF_UNSPEC; 
    if (sock=="tcp") { 
    hints.ai_socktype=SOCK_STREAM; 
    } else if (sock=="udp") { 
     hints.ai_socktype=SOCK_DGRAM; 
    } else { 
     fprintf(stderr,"[!] xsockets: error: unknown socket type %s\n",sock); 
     exit(2); 
    } 
    hints.ai_flags=AI_PASSIVE; 

    if ((status=getaddrinfo(host,service,&hints,&serv))!=0) { 
     fprintf(stderr, "[!] xsockets: error: getaddrinfo error: %s\n",  gai_strerror(status)); 
     exit(1); 
    } 
    cout << "3.setup() returns here.\n"; 
    return *serv; 
} 

/** 
* Listens on a portand returns a scoket file descriptor. 
* @param service The service on this machine (e.g "http" or "80") 
* @param sock The type of socket ("tcp" or "udp") 
* @return A socket filde descriptor. 
*/ 
int listen(const char *service,const char *sock) { 
    cout << "1.call to listen()\n"; 
    struct addrinfo *serv; 
    *serv=setup(NULL,service,sock); 
    cout << "4.is this ever called?"; 
    int sockfd=socket(serv->ai_family,serv->ai_socktype,serv->ai_protocol); 
    int status=bind(sockfd,serv->ai_addr,serv->ai_addrlen); 
    if (status!=0) { 
     fprintf(stderr,"[!] xsockets: error: bind error:       %s\n",gai_strerror(status)); 
     exit(3); 
} 
    cout << "5.listen() returns here."; 
    return sockfd; 
} 
#endif 

Если я запускаю это, он получает до # 3 «Настройка() возвращает здесь», но никогда не выходит на # 4 гораздо меньше # 5 "listen() возвращается сюда"

Может ли кто-нибудь сказать мне, что пошло не так.

Я нахожусь в Ubuntu Linux, используя это с привилегиями root. Он был скомпилирован командой g++.

Вот что я получаю:

+3

Во-первых, использовать отладчик не печатать заявления. Во-вторых, он, вероятно, попадает туда, но выходной буфер не сбрасывается, прежде чем что-то еще вызывает сбой - вы можете сбросить(), чтобы заставить это, и я думаю, вы можете cout << endl, хотя я не уверен, что это будет сделай это. В-третьих, вы должны описать, какое поведение вы действительно видите. Это очень важно, как ожидаемое поведение при диагностике ошибки. – atk

+2

Вместо cout используйте std :: cerr, чтобы все, что вы пишете на него, сразу же очистилось. –

+1

Почему вы возвращаете значение 'addrinfo' struct by-value? Вы должны вернуть указатель. Вы также пропускаете память - вы должны вызывать 'freeaddrinfo()' на значение, возвращаемое 'getaddrinfo()' (и * not * на копии базовой структуры 'addrinfo'). –

ответ

3

Вы неопределенное поведение, потому что вы не инициализировать указатель serv, но затем сразу же разыменования его с *serv.

Тем не менее, при отладке, вы должны убедиться, что выход сбрасывается путем вставки std::flush или std::endl в std::cout:

cout << "4.is this ever called?" << std::endl; 
+0

О да, я делал это, потому что думал, что это может что-то связать с вызовом setup() и возвратом listen(). Даже при этом, это и покраснение, он все равно не работает. – roperson

+1

... или просто используйте 'std :: cerr' вместо' std :: cout', который автоматически сбрасывается для таких ситуаций. –

2

У вас есть некоторые основные проблемы:

  1. Вы надеваете» t выделяет память для serv.

    struct addrinfo *serv;

    *serv=setup(NULL,service,sock);

  2. вы не проверяют возвращаемые значения большинства функций int sockfd например.

  3. Вы объявляете вещи в стеке, а не глобально, попытайтесь выяснить, что - это область каждой переменной.

    struct addrinfo hints; 
    struct addrinfo *serv; 
    
Смежные вопросы