tags:

views:

92

answers:

2

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
+3  A: 

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 );
}
Dean Harding
I've edited the file based of what you said. Still have an issue.
dbdii407
@dbdii407: Do you check the value of `errno`? What does it say?
Dean Harding
Yes, That's the error I got. "Network is unreachable"And ScrapIRC is my network. It works. There's something weird with this code that I can't figure out.
dbdii407
+1  A: 

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) );
    }
}
Robert S. Barnes
Even with your changes, There's still issues. h->h_addr_list[0] returns B�Z and the inet_addr makes it 4294967295. No clue what that means but just throwing it out there.
dbdii407
@dbdii407: Here is the working program. I suggest getting a good book on C++ programming such as Accelerated C++ by Koenig.
Robert S. Barnes