PDA

View Full Version : TCP sockets classes



Camel
12-16-2006, 06:45 AM
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


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

Salem
12-16-2006, 07:07 AM
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.

Camel
12-16-2006, 07:19 AM
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. ;)

Camel
12-16-2006, 07:52 PM
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


error recving data
recv() returned -1
0


This is obviously not correct. recv() returns -1 but h_errno says there was no error.

:confused:

Salem
12-17-2006, 02:18 AM
> 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.

Cactus_Hugger
12-17-2006, 07:29 PM
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)