C++的Socket连接错误

C++的Socket连接错误

问题描述:

编辑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

我认为问题在于这一行:

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

我决定完全重做我的答案,部分原因是由于在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