2013-10-11 5 views
1

Итак, я писал класс C++, чтобы сделать сокеты UNIX в c немного проще. Однако каждый раз, когда я запускаю его, он не может подключиться. Значение порта изменяется в середине программы. Вот заголовочный файл с классом:Значение C++ int Загадочные изменения

#ifndef __Sockets__CHSocket__ 
#define __Sockets__CHSocket__ 
class Sock { 
    int port; 
    char host[16]; 
    int sock,maxLen; 
    int bytes; 
    long nHostAddress; 
    struct hostent* pHostInfo; 
    struct sockaddr_in dest; 

public: 
    Sock(int dom, int type); 
    int connct(const char *host, int port); 
    int bnd(const char *addr, int port); 
    int lstn(int port); 
    int snd(const char *toSend); 
    int sndto(const char *msg, const char *dst); 
    char* recv(int length); 
    int accpt(int s, struct sockaddr *addr, socklen_t *addrlen); 
    int clse(); 
}; 
#endif /* defined(__Sockets__CHSocket__) */ 

Здесь CHSocket.cpp (укорачивается до того, что на самом деле запустить):

// Constructor definition 
Sock::Sock(int dom, int type) 
{ 
    bzero(&dest, sizeof(dest)); 
    if ((sock=socket(dom, type, 0)<0)) { 
     cerr << "[!] Failed to create socket!;"; 
    } 
    dest.sin_family=dom; 
    memset(&dest, 0, sizeof(dest)); 
} 

// Connect definition 
int Sock::connct(const char *host, int port) 
{ 
    char theHost[sizeof(host)]; 
    strcpy(theHost, host); 
    pHostInfo=gethostbyname(theHost); 
    memcpy(&nHostAddress,pHostInfo->h_addr,pHostInfo->h_length); 

    dest.sin_addr.s_addr=nHostAddress; 
    dest.sin_port = htons(port); 
    if (connect(sock, (struct sockaddr *)&dest, sizeof(dest)) < 0) 
    { 
     cerr << "[!] Failed to connect socket!"; 
     return -1; 
    } 
    else 
    { 
     return 0; 
    } 
    return 0; 
} 

Вот main.cpp:

int main() 
{ 
    Sock test = Sock(AF_INET, SOCK_STREAM); 
    test.connct("127.0.0.1", 3000); 
    test.clse(); 
} 

Я использую xcode 5 на osx 10.8. Когда я запустил программу, мне сказали, что она не может подключиться. Я поставил некоторые точки останова в самом начале функции connect и в строке, которая определяет pHostInfo. В первой точке останова значение порта равно 3000, а во втором - 49. Связано ли это с проблемой подключения?

UPDATE:

Программа работает сейчас, но это дает мне следующий вывод:

[!] Failed to connect socket!Program ended with exit code: 0 

Это то, что он делает, когда он не в состоянии соединить гнездо. У меня неткарт, прослушивающий порт 3000, и я успешно подключился из другого окна. Есть идеи, что может быть проблемой?

+1

Вы используете [зарезервированный идентификатор] (HTTP: // stackoverf low.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier). – chris

+3

Я не хочу быть суровым, но с такими именами функций я бы использовал оригинальный API над вашим без каких-либо колебаний. – syam

+0

@syam это не имеет отношения к вопросу, но все же вы правы. это уже не 1987, у компьютеров много памяти, больше нет необходимости сохранять ее для этой цели. – ipinak

ответ

3
char theHost[sizeof(host)]; 

Эта линия выделяет достаточное количество байтов, чтобы просто сохранить размер host, который является указателем на символ, который, вероятно, будет 8. перезаписывает номер порта, потому что вам не хватает памяти, выделенной на стек. Вы, вероятно, хотите следующее:

char *theHost = new char[strlen(host)+1] 

и затем свободно, что память после этого, перед вашими конструкторами возвращений:

delete [] theHost; 

В качестве альтернативы, и проще и лучше, вы можете просто использовать host аргумент непосредственно в вызове в gethostbyname()

редактировать: (добавлено открепление, как это было предложено)

+0

Если вы собираетесь рекомендовать динамическое распределение, стоит упомянуть о необходимости позже вызывать 'delete []' – simonc

+0

@simonc или просто умные указатели. – syam

+2

Или просто используйте 'std :: string' ... – GManNickG

3
char theHost[sizeof(host)]; 

дает массив с пространством для sizeof(char*). Вы действительно нуждаетесь в strlen(host)+1 байтах, так что, вероятно, переписывая память внутри последующего strcpy. Для этого потребуется либо поддержка VLA (которая отсутствует как стандартная), либо ненужное динамическое распределение.

Было бы проще просто удалить theHost, используя для этого host.

+2

В зависимости от компилятора 'gcc' и' clang' поддерживают VLA как [расширение на C++.] (Http://stackoverflow.com/a/19136083/1708801) –

+0

@ShafikYaghmour Спасибо, я этого не знал. Я обновил свой ответ. – simonc

+2

C++ 14 также имеет VLA. – chris

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