TCP sockets classes

This is a discussion on TCP sockets classes within the Linux Programming forums, part of the Platform Specific Boards category; I am trying to create a simple library for using TCP sockets. There are three classes, a main socket class, ...

  1. #1
    Registered User Camel's Avatar
    Join Date
    Dec 2006
    Location
    Australia
    Posts
    3

    TCP sockets classes

    I am trying to create a simple library for using TCP sockets. There are three classes, a main socket class, a class for a server and a class for a client. The main socket class is publicly inherited by the other classes. When a client calls scSend() the function works fine and the data is sent. However when a server calls either scSend() or scRecv() it fails and prints an error message. Why?

    Here is the relavent code

    Code:
    class scSocket
    {
       public:
          int scSend(char* data, int size);
          int scRecv(char* data, int size);
    
          int scRecvcallback();
    
          int scGetlasterror();
    
       protected:
          int sock;
          int error;
    };
    
    
    class scClient : public scSocket
    {
       public:
          scClient();
          scClient(char* host, int port);
    
          ~scClient();
    
    
          int scConnect(char* host, int port);
    
       protected:
          bool scTryhostname(char* host, int port);
          bool scTryip(char* host, int port);
          
          struct sockaddr_in server;
          struct hostent *server2;
          
    };
    
    
    class scServer : public scSocket
    {
       public:
          scServer();
          scServer(int port);
          ~scServer();
    
          int scListen(int port);
    
       protected:
          int listener;
          struct sockaddr_in aserver, aclient;
    };
    
    
    int scSocket::scSend(char* data, int size)
    {
       int ret = write(sock, data, size);
       if(ret != size)
       {
          cout << "error sending data\nsend returned " << ret << endl;
          error = 4;
          return ret;
       }
       cout << "data sent" << endl;
       return 0;
    }
    
    int scSocket::scRecv(char* data, int size)
    {
       int ret = read(sock, data, size);
       if(ret < 0)
       {
          cout << "error recving data\nrecv() returned " << ret << endl;
          error = 4;
       }
       cout << "data recved" << endl;
       return ret;
    }
    
    int scServer::scListen(int port)
    {
       memset(&aserver, 0, sizeof(aserver));
       aserver.sin_family = AF_INET;
       aserver.sin_addr.s_addr = htonl(INADDR_ANY);
       aserver.sin_port = htons(port);
    
       if(bind(listener, (struct sockaddr *) &aserver, sizeof(aserver)) < 0)
       {
          cout << "error binding socket!\n";
          error = 1;
          return -1;
       }
    
       cout << "socket bound\n";
       listen(listener, 5);
       cout << "listening . . .\n";
       unsigned int clen = sizeof(aclient);
    
       if(sock = accept(listener, (struct sockaddr *) &aclient, &clen) < 0)
       {
          cout << "error accepting client!\n";
          error = 3;
          return -3;
       }
    
       cout << "connection accepted!\n";
       return 1;
    }
    
    
    scServer::scServer()
    {
       listener = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
       if(listener < 0)
       {
          cout << "error creating listener socket" << endl;
          error = 1;
       }
       cout << "socket created\n";
    }
    
    
    int main()
    {
       scServer ss(4651);
    
       char buf[50];
       bzero(buf, 50);
    
       ss.scRecv(buf, 50);
    
       cout << buf << endl;
    }

  2. #2
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,592
    I dont see any obvious place where scServer::scListen is called from.

    Can you be more specific than "an error" ?

    A lot of things set a variable called errno (which you can print with perror(), or get a meaningful description with strerror() )
    Use that to tell you why things are not working.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  3. #3
    Registered User Camel's Avatar
    Join Date
    Dec 2006
    Location
    Australia
    Posts
    3
    Quote Originally Posted by Salem
    I dont see any obvious place where scServer::scListen is called from.

    Can you be more specific than "an error" ?

    A lot of things set a variable called errno (which you can print with perror(), or get a meaningful description with strerror() )
    Use that to tell you why things are not working.
    scServer::scListen is called in the overloaded constructor scServer(int port).

    The error is scSocket::scRecv() always prints out the error message and returns -1.

    Im googling for info about errno now.

  4. #4
    Registered User Camel's Avatar
    Join Date
    Dec 2006
    Location
    Australia
    Posts
    3
    Code:
    int scSocket::scRecv(char* data, int size)
    {
    	cout << "waiting to recv data\n";
    	int ret = recv(sock, data, size, 0);
    	if(ret < 0)
    	{
    		cout << "error recving data\nrecv() returned " << ret << endl;
    		cout << h_errno << endl;
    		error = 4;
    	}
    	cout << "data recved" << endl;
    	return ret;
    }
    Output from this function
    Code:
    error recving data
    recv() returned -1
    0
    This is obviously not correct. recv() returns -1 but h_errno says there was no error.


  5. #5
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,592
    > scServer::scListen is called in the overloaded constructor scServer(int port).
    I'm assuming this is in some code you didn't post.

    > cout << h_errno << endl;
    Except I said errno.
    h_errno is only used by the 'gethost' functions AFAIK.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  6. #6
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    I can't see anything terribly wrong to cause what you're describing. Some things to try:
    In scRecv(), what is the value of sock? (Is it a valid socket?)
    Is data actually sent from the other end? (Ethereal is a great program for that)
    long time; /* know C? */
    Unprecedented performance: Nothing ever ran this slow before.
    Any sufficiently advanced bug is indistinguishable from a feature.
    Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
    The best way to accelerate an IBM is at 9.8 m/s/s.
    recursion (re - cur' - zhun) n. 1. (see recursion)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. TCP Header problem (error)
    By nasim751 in forum C Programming
    Replies: 1
    Last Post: 04-25-2008, 07:30 AM
  2. TCP Sockets: multiple clients - one server
    By Printisor in forum C Programming
    Replies: 4
    Last Post: 11-01-2007, 10:34 AM
  3. Accessing TCP flags in TCP packets on Linux using C !!
    By vishamr in forum Linux Programming
    Replies: 2
    Last Post: 10-16-2006, 08:48 AM
  4. Implementing timeouts with TCP sockets
    By nkhambal in forum C Programming
    Replies: 2
    Last Post: 04-13-2005, 11:10 PM
  5. Can TCP sockets also receive ICMP...?
    By failure_to in forum Networking/Device Communication
    Replies: 3
    Last Post: 06-09-2004, 10:36 AM

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