C Board  

Go Back   C Board > General Programming Boards > C++ Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 11-22-2005, 03:24 AM   #1
Maz
Registered User
 
Join Date: Nov 2005
Posts: 146
inet_aton()... Noob needs help with sockets :|

Hi dee Ho again.

I started learning how to toy with sockets yesterday... Well, I am utterly confused with the structures && functions dealing with ports & hostnames, with client & server sockets, with this & that

Basically what I would like to do is connect to certain server(s) & be able to send & receive data. I've done that with php sockets, so I assume I should be able to do it with c++ too

I prepared following class for that:
connect.h:

Code:
#ifndef _CONNECT
#define _CONNECT
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

using namespace std;

class Connect {

private:

        int sock;
        struct sockaddr_in serv_addr;

public:
        Connect(){;}
        ~Connect()
                {
                close(this->sock);
                }
        int con(string host, int port); //open socket
        int send_command(string command);
        int send_payload(string command);
        char *receive();
};

#endif
and connect.cpp:
Code:
#include "connect.h"
#include <iostream>
#include <string.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <ctype.h>
#include <stdlib.h>
#include <netdb.h>

using namespace std;

int Connect::con(string host, int port)
{
        struct hostent *h;



        char *ip;

        //int success;


        if((h=gethostbyname(host.c_str()))==NULL)
        {
                herror("gethostbyname");
                exit(1);
        }

        ip=inet_ntoa(*((struct in_addr *)h->h_addr));


        if((this->sock = socket(AF_INET, SOCK_STREAM, 0)) < 0 )   //Lets make the filedescriptor
        {
                cout << "Smelly Socks!" << endl;
                exit(-666);
        }

        /*Lets connect to server*/
        serv_addr.sin_family = AF_INET;
        if( inet_aton(ip,&serv_addr.sin_addr) !=0 )
        {
                cout << "invalid ip format: " << ip << endl;
                exit(1);
        }
        serv_addr.sin_port = htons(port);

        if(connect(sock,(struct sockaddr *) &serv_addr, sizeof(serv_addr))<0)
        {
                cout << "Connecting to " << ip << " failed" << endl;
                exit(-666);
        }
        return 1;
}

int Connect::send_command(string command)
{
        int len;
        len=strlen(command.c_str())+2;

        command=command+"\r\n";
        write(sock,command.c_str(),len);
        cout << "SENT : " << command << endl;
        return 1;
}

int Connect::send_payload(string command)
{
        int len;
        len=strlen(command.c_str());
        cout << "SENT : " << command << endl;

        write(sock,command.c_str(),len);
        return 1;

}

char *Connect::receive()
{
        char *buf;
        int nread;
        nread=read(this->sock,buf,1024);
        cout << "GOT : " << buf << endl;
        return buf;
}

Now when I try to use it to connect to a certain server & send command inet_aton fails (it returns something that's not 0, and according to man pages it should not.)

(this
Code:
 if( inet_aton(ip,&serv_addr.sin_addr) !=0 )
        {
                cout << "invalid ip format: " << ip << endl;
                exit(1);
        }
Any ideas what's wrong? And can use this kind of class to do the connection? As I said, I am a noob with sockets, and the structures & handling of ip's / hostnames are mostly just taken from examples...

If someone feels like explaining them (structures & functions to manipulate hostnames/ips) well, feel free, (that would really help me understanding them better, cause the tutos I found just stated there is such structures, but the purpose is not terribly clear :/) but I would also be gratefull if someone just could tell me why inet_aton does not work.

Oh, BTW. I am using linux & g++ compiler.

Last edited by Maz; 11-22-2005 at 03:27 AM.
Maz is offline   Reply With Quote
Old 11-22-2005, 08:54 AM   #2
Registered User
 
Join Date: Nov 2005
Posts: 52
Here's a good guide to low-level socket programming:
http://beej.us/guide/bgnet/output/html/
<edit> Updated to the current page</edit>

And here's an implementation of an iostream-friendly socket class hierarchy that works on Linux, and probably other Unix systems:
http://www.linuxhacker.at/socketxx

The first one will explain the structures/functions pretty well, and the second can show you how to use them in C++ (or just let you use a nicely built socket library as-is).

Last edited by Stuka; 11-22-2005 at 08:58 AM.
Stuka is offline   Reply With Quote
Old 11-22-2005, 02:45 PM   #3
Maz
Registered User
 
Join Date: Nov 2005
Posts: 146
Oh. The problem with inet_aton() was so silly... I had misread the manpages inet_aton() returns 0 if theres error, othervice it returns something else So I had the errorchecking wrong way

Anyways, now when I use the class with following "main" function:
Code:
#include "connect.h"
#include <iostream>
#include <string.h>
#include <string.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <ctype.h>
#include <stdlib.h>
#include <ctype.h>

using namespace std;

std::string itoa(int value, unsigned int base);

int main()
{
        char *dumb;
        int trid=0,socketti;
        Connect msn;
        string command;

        socketti=msn.con("messenger.hotmail.com",1863);
        command="VER "+itoa(trid++,10)+" MSNP9 CVR0\r\n";

        msn.send_command(command);
        cout << msn.receive();
}

/*
The following itoa() has been found from the web with google.
I just can't remember who the author was.
Anyways, I have not done it, and if someone knows the
author, please mention him :)

*/

std::string itoa(int value, unsigned int base)
{

        const char digitMap[] = "0123456789abcdef";
        std::string buf;

        // Guard:
        if (base == 0 || base > 16) {
                // Error: may add more trace/log output here
                return buf;
        }

        // Take care of negative int:

        std::string sign;
        int _value = value;

        // Check for case when input is zero:
        if (_value == 0) return "0";
        if (value < 0) {
                _value = -value;
                sign = "-";
        }

        // Translating number to string with base:
        for (int i = 30; _value && i ; --i) {
                buf = digitMap[ _value % base ] + buf;
                _value /= base;
        }
        return sign.append(buf);
}
It outputs following text:
Quote:

SENT : VER 0 MSNP9 CVR0


GOT : VER 0 MSNP9 CVR0

VER 0 MSNP9 CVR0
14212: binding file ./msn to /usr/lib/libstdc++.so.5: normal symbol `_ZNSi6ignoreEii' [GLIBCPP_3.2]
14212: binding file /usr/lib/libstdc++.so.5 to /usr/lib/libstdc++.so.5: normal symbol `_ZNSi6sentryC1ERSib' [GLIBCPP_3.2]
14212: binding file /usr/lib/libstdc++.so.5 to /usr/lib/libstdc++.so.5: normal symbol `_ZNSt15basic_streambufIcSt11char_traitsIcEE6sbump cEv' [GLIBCPP_3.2]
14212: binding file /usr/lib/libstdc++.so.5 to /usr/lib/libstdc++.so.5: normal symbol `_ZNSt13basic_filebufIcSt11char_traitsIcEE19_M_und erflow_commonEb' [GLIBCPP_3.2]
14212: binding file /usr/lib/libstdc++.so.5 to /usr/lib/libstdc++.so.5: normal symbol `_ZNSt12__basic_fileIcE6xsgetnEPci' [GLIBCPP_3.2]
14212: binding file /usr/lib/libstdc++.so.5 to /lib/tls/libc.so.6: normal symbol `fread' [GLIBC_2.0]
14212: binding file ./msn to /usr/lib/libstdc++.so.5: normal symbol `_ZStrsIcSt11char_traitsIcEERSt13basic_istreamIT_T 0_ES6_PS3_' [GLIBCPP_3.2]

14212: binding file /usr/lib/libstdc++.so.5 to /usr/lib/libstdc++.so.5: normal symbol `_ZNSt12__basic_fileIcE10sys_ungetcEi' [GLIBCPP_3.2]
14212: binding file /usr/lib/libstdc++.so.5 to /lib/tls/libc.so.6: normal symbol `ungetc' [GLIBC_2.0]



ds
14212: binding file ./msn to /lib/tls/libc.so.6: normal symbol `close' [GLIBC_2.0]
14212: binding file ./msn to /usr/lib/libstdc++.so.5: normal symbol `_ZNSt8ios_base4InitD1Ev' [GLIBCPP_3.2]
14212:
14212: calling fini: /usr/lib/libstdc++.so.5
14212:
14212: binding file /usr/lib/libstdc++.so.5 to /lib/tls/libc.so.6: normal symbol `__cxa_finalize' [GLIBC_2.1.3]
14212: binding file /usr/lib/libstdc++.so.5 to /usr/lib/libstdc++.so.5: normal symbol `_ZNSt8ios_base4InitD1Ev' [GLIBCPP_3.2]
14212: binding file /usr/lib/libstdc++.so.5 to /usr/lib/libstdc++.so.5: normal symbol `_ZNSt8ios_base4Init14_S_ios_destroyEv' [GLIBCPP_3.2]
14212: binding file /usr/lib/libstdc++.so.5 to /usr/lib/libstdc++.so.5: normal symbol `_ZNSt13basic_filebufIcSt11char_traitsIcEE5closeEv ' [GLIBCPP_3.2]
14212: binding file /usr/lib/libstdc++.so.5 to /usr/lib/libstdc++.so.5: normal symbol `_ZNSt13basic_filebufIcSt11char_traitsIcEE26_M_des troy_internal_bufferEv' [GLIBCPP_3.2]
14212: binding file /usr/lib/libstdc++.so.5 to /usr/lib/libstdc++.so.5: normal symbol `_ZNSt12__basic_fileIcE5closeEv' [GLIBCPP_3.2]
14212: binding file /usr/lib/libstdc++.so.5 to /usr/lib/libstdc++.so.5: normal symbol `_ZNSt12__basic_fileIcED1Ev' [GLIBCPP_3.2]
14212: binding file /usr/lib/libstdc++.so.5 to /usr/lib/libstdc++.so.5: normal symbol `_ZNSt13basic_filebufIwSt11char_traitsIwEE5closeEv ' [GLIBCPP_3.2]
14212: binding file /usr/lib/libstdc++.so.5 to /usr/lib/libstdc++.so.5: normal symbol `_ZNSt13basic_filebufIwSt11char_traitsIwEE26_M_des troy_internal_bufferEv' [GLIBCPP_3.2]
14212:
14212: calling fini: /lib/tls/libm.so.6
14212:
14212: binding file /lib/tls/libm.so.6 to /lib/tls/libc.so.6: normal symbol `__cxa_finalize' [GLIBC_2.1.3]
14212:
14212: calling fini: /lib/libgcc_s.so.1
14212:
14212: binding file /lib/libgcc_s.so.1 to /lib/tls/libc.so.6: normal symbol `__cxa_finalize' [GLIBC_2.1.3]
14212:
14212: calling fini: /lib/libnss_files.so.2
14212:
14212: binding file /lib/libnss_files.so.2 to /lib/tls/libc.so.6: normal symbol `__cxa_finalize' [GLIBC_2.1.3]
14212:
14212: calling fini: /lib/libnss_dns.so.2
14212:
14212: binding file /lib/libnss_dns.so.2 to /lib/tls/libc.so.6: normal symbol `__cxa_finalize' [GLIBC_2.1.3]
14212:
14212: calling fini: /lib/libresolv.so.2
14212:
14212: binding file /lib/libresolv.so.2 to /lib/tls/libc.so.6: normal symbol `__cxa_finalize' [GLIBC_2.1.3]
14212:
14212: calling fini: /lib/tls/libc.so.6
14212:
Well, that's not actually what I did expect... Does anyone notice any more errors? Perhaps theres something wrong in the way I output the contents of the socket??? or??

Please do not toast me if this question is silly, I really am a newbie with sockets
Maz is offline   Reply With Quote
Old 11-22-2005, 04:33 PM   #4
Maz
Registered User
 
Join Date: Nov 2005
Posts: 146
Okay, I found the bug. It was really stupid one...
I accidentally added \r\n twice at the end of the command, once in main.cpp and then again in send_command function... Sorry for bugging you
Maz is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
File transfer over sockets adrians C Programming 3 03-02-2009 12:56 AM
Best way to poll sockets? 39ster Networking/Device Communication 3 07-22-2008 01:43 PM
multiple UDP sockets with select() nkhambal Networking/Device Communication 2 01-17-2006 07:36 PM
Raw Sockets and SP2... Devil Panther Networking/Device Communication 11 08-12-2005 04:52 AM
Starting window sockets _Cl0wn_ Windows Programming 2 01-20-2003 11:49 AM


All times are GMT -6. The time now is 02:37 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22