简体   繁体   English

C ++套接字连接错误

[英]C++ Socket Connection Error

EDIT 编辑

I've made changes to what I saw below and this is what I have 我对以下内容进行了更改,这就是我所拥有的

#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) );
    }
  }

And this is the result: 结果如下:

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

I think the problem is that this line: 我认为问题是这一行:

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

Is not doing what you think it's doing. 没有按照自己的想法去做。 argv[2] is a string, *argv[2] is the first character of the string. argv[2]是字符串, *argv[2]是字符串的第一个字符。 So if you passed "4567" as the second command-line argument, then *argv[2] will be '4' which has ASCII value 52. That means you'll be attempting to connect to port 52, not "4567" as you would expect. 因此,如果您将“ 4567”作为第二个命令行参数传递,则*argv[2]将为“ 4”,其ASCII值为52。这意味着您将尝试连接到端口52,而不是“ 4567”,您会期望的。

Change the line to: 将行更改为:

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

The atoi function takes a string and converts it to an integer. atoi函数采用字符串并将其转换为整数。 So "4567" would become 4567. 因此,“ 4567”将变为4567。

Also, in general, you should check the value of errno when a function call like that fails (it'll usually tell you in the documentation whether errno is set and the possible values it can be set to). 同样,通常,当类似的函数调用失败时,您应该检查errno的值(通常会在文档中告诉您是否设置了errno以及可以将其设置为可能的值)。 That should help to give you some clue in the future. 这应该有助于将来为您提供一些线索。

Edit 编辑
As others have noted, make sure you pay attention to your braces. 正如其他人指出的那样,请确保您注意大括号。 It's usually easier if you just always use braces around if , while , and so on. 它通常是更容易,如果你只是始终在用大括号ifwhile ,等等。 That is, this: 也就是说,这是:

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

Is completely different to this: 与此完全不同:

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

I decided to completely redo my answer, in part due to the following comment in the gethostbyname manpage: 我决定完全重做我的答案,部分原因是gethostbyname页中的以下注释:

The gethostbyname*() and gethostbyaddr*() functions are obsolete. gethostbyname *()和gethostbyaddr *()函数已过时。 Applications should use getaddrinfo(3) and getnameinfo(3) instead. 应用程序应改用getaddrinfo(3)和getnameinfo(3)。

Here is the reworked program ( cleaned up a bit with bcpp ) based on using getaddrinfo . 这是基于使用getaddrinfo的重做程序(用bcpp清理了一点)。 I would strongly suggest always compiling with the following options: 我强烈建议始终使用以下选项进行编译:

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

This showed up the following bugs in your code: 这在您的代码中显示了以下错误:

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

I went ahead and fixed the errors. 我继续并修复了错误。 Also, try and eliminate global variables as much as possible. 另外,请尝试并尽可能消除全局变量。

#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) );
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM