2010-06-23 274 views
1

編輯C++的Socket連接錯誤

我已經更改我下面什麼看到的,這是我

#include <sys/socket.h> 
#include <netinet/in.h> 
#include <sys/un.h> 
#include <arpa/inet.h> 
#include <netdb.h> 
#include <string> 
#include <vector> 
#include <iostream> 
#include <cstring> 
#include <cstdlib> 
#include <errno.h> 

using namespace std; 

string buffer; 
vector<string> ex; 
int s; 

void recvline (int s, string* buf) { 
    char in, t; 
    while (1) { 
    recv (s, &in, 1, 0); 
    *buf += in; 
    if (in == 10) { 
     t = 1; } 
    if (t && in == 13) { 
     break; } 
    } 
    } 

void push (int s, string msg) { 
    string o = msg + "\r\n"; 
    cout << "SENT:", o; 
    send (s, o.c_str(), o.size(), 0); 
    } 

int main (int argc, char *argv[]) { 
    if (argc < 3) { 
    cout << "Insufficient Arguments" << endl; 
    exit (7); } 
    s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); 
    if (s < 0) 
    exit (1); 
    struct hostent h = *gethostbyname (argv[1]); 
    struct sockaddr_in c; 
    c.sin_family = AF_INET; 
    c.sin_port = htons(atoi(argv[2])); 
    c.sin_addr.s_addr = inet_addr (h.h_addr_list[0]); 
    if (connect (s, (struct sockaddr*)&c, sizeof c) != 0) { 
     cout << "Unable to connect to network" << endl; 
     cout << strerror(errno) << endl; 
     exit (2); 
    } 
    push (s, "USER LOLwat Lw lol.wat :LOLwat"); 
    push (s, "NICK LOLwat"); 
    while (true) { 
    recvline (s, &buffer); 
    cout << buffer; 
    if (buffer.substr(0,4).c_str() == "PING") 
     push (s, "PONG " + buffer.substr(6,-2)); 
    } 
    } 

這是結果:

[[email protected] Desktop]$ g++ ?.cpp -o 4096 - 
[[email protected] Desktop]$ ./4096 irc.scrapirc.com 6667 - Unable to connect to network - Network is unreachable 
+1

您應該檢查'errno'的值來查看實際的錯誤是什麼。 – 2010-06-23 04:26:31

+1

另外,注意你的大括號 - 有一些地方縮進建議兩行將一起執行,但他們不(例如,在無法連接到網絡錯誤之後)。我建議使用自動縮進編輯器或其他東西。 – bdonlan 2010-06-23 04:27:54

+0

*總是*使用花括號。 C不是Python。 – 2010-06-23 04:31:03

回答

3

我認爲問題在於這一行:

c.sin_port = htons(*argv[2]); 

是不是在做你認爲它在做的事情。 argv[2]是一個字符串,*argv[2]是該字符串的第一個字符。所以如果你通過「4567」作爲第二個命令行參數,那麼*argv[2]將是'4',它的ASCII值爲52.這意味着你將試圖連接到端口52,而不是你所期望的那樣連接到「4567」。

行更改爲:

c.sin_port = htons(atoi(argv[2])); 

atoi函數採用一個串並將其轉換成一個整數。因此,「4567」將成爲4567

而且,在一般情況下,你應該在這樣的一個函數調用失敗檢查errno值(它通常會告訴你在the documentation是否將errno設置和可能的值,它可以被設置爲)。這應該有助於在未來給你一些線索。

編輯
正如其他人所指出的,請務必注意你的牙套。如果您只需總是使用大括號ifwhile等等,通常會更容易。也就是說,這樣的:

if (connect (s, (struct sockaddr*)&c, sizeof c) != 0) 
    cout << "Unable to connect to network" << endl; 
    exit (2); 

與此完全不同:

if (connect (s, (struct sockaddr*)&c, sizeof c) != 0) { 
    cout << "Unable to connect to network" << endl; 
    exit (2); 
} 
+0

我已經根據你所說的編輯了文件。仍然有問題。 – dbdii407 2010-06-23 14:20:15

+0

@ dbdii407:你檢查'errno'的值嗎?它說什麼? – 2010-06-23 21:00:21

+0

是的,這是我得到的錯誤。 「網絡無法訪問」 ScrapIRC是我的網絡。有用。這個代碼有些奇怪,我無法弄清楚。 – dbdii407 2010-06-23 22:15:13

2

我決定完全重做我的答案,部分原因是由於在gethostbyname手冊頁的評論:

gethostbyname *()和 gethostbyaddr *()函數是 已過時。應用程序應該使用 getaddrinfo(3)和getnameinfo(3) 。

這是重做的程序(根據使用getaddrinfo使用bcpp清理了一下)。我強烈建議總是與下列選項編譯:

g++ -Wall -Wextra irc.cpp -o irc 

這顯示了以下錯誤在你的代碼:

irc.cpp: In function ‘void push(int, std::string)’: 
irc.cpp:40: warning: right-hand operand of comma has no effect 
irc.cpp: In function ‘int main(int, char**)’: 
irc.cpp:87: warning: comparison with string literal results in unspecified behaviour 

我繼續和修復錯誤。此外,儘可能嘗試並消除全局變量。

#include <sys/socket.h> 
#include <netinet/in.h> 
#include <sys/un.h> 
#include <arpa/inet.h> 
#include <netdb.h> 
#include <string> 
#include <vector> 
#include <iostream> 
#include <cstring> 
#include <cstdlib> 
#include <errno.h> 

using namespace std; 

string buffer; 
vector<string> ex; 

void recvline (int s, string* buf) 
{ 
    char in, t; 
    while (1) 
    { 
     recv (s, &in, 1, 0); 
     *buf += in; 
     if (in == 10) 
     { 
      t = 1; 
     } 
     if (t && in == 13) 
     { 
      break; 
     } 
    } 
} 


void push (int s, string msg) 
{ 
    string o = msg + "\r\n"; 
    cout << "SENT:" << o; 
    send (s, o.c_str(), o.size(), 0); 
} 


int main (int argc, char *argv[]) 
{ 
    if (argc < 3) 
    { 
     cout << "Insufficient Arguments" << endl; 
     exit (7); 
    } 

    int s, sfd; 
    struct addrinfo *result, *rp; 

    s = getaddrinfo(argv[1], argv[2], NULL, &result); 
    if (s != 0) { 
     fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s)); 
     exit(EXIT_FAILURE); 
    } 

    for (rp = result; rp != NULL; rp = rp->ai_next) { 
     sfd = socket(rp->ai_family, rp->ai_socktype, 
        rp->ai_protocol); 
     if (sfd == -1) 
      continue; 

     if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1) 
      break;     /* Success */ 

     close(sfd); 
    } 

    if (rp == NULL) {    /* No address succeeded */ 
     fprintf(stderr, "Could not connect\n"); 
     exit(EXIT_FAILURE); 
    } 

    freeaddrinfo(result);   /* No longer needed */ 

    push (sfd, "USER LOLwat Lw lol.wat :LOLwat"); 
    push (sfd, "NICK LOLwat"); 
    while (true) 
    { 
     recvline (sfd, &buffer); 
     cout << buffer; 
     if (buffer.substr(0,4) == "PING") 
      push (sfd, "PONG " + buffer.substr(6,-2)); 
    } 
} 
+0

即使您的更改仍然存在問題。 h-> h_addr_list [0]返回B Z,inet_addr使它成爲4294967295.不知道這意味着什麼,只是把它扔到那裏。 – dbdii407 2010-06-24 14:02:46

+0

@ dbdii407:這是工作程序。我建議在C++編程方面寫一本好書,比如Koenig的Accelerated C++。 – 2010-06-25 11:43:16