简体   繁体   中英

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. 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.

Change the line to:

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

The atoi function takes a string and converts it to an integer. So "4567" would become 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). 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. 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:

The gethostbyname*() and gethostbyaddr*() functions are obsolete. Applications should use getaddrinfo(3) and getnameinfo(3) instead.

Here is the reworked program ( cleaned up a bit with bcpp ) based on using getaddrinfo . 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) );
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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