Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old May 22nd, 2006, 5:18 PM   #11
hbe02
Hobbyist Programmer
 
hbe02's Avatar
 
Join Date: Mar 2006
Location: Lebanon
Posts: 148
Rep Power: 3 hbe02 is on a distinguished road
As part of my first sockets program.. i created a sockets class.. where you can create a socket.. and send or recieve through it...
Please feel free to give any feedback or suggestions..
#ifndef SOCKET_H
#define SOCKET_H

#include<WinSock2.h>
#include<iostream>

using namespace std;

class Mysocket{

private:

	void WinConnect();
	void GetInfo(sockaddr_in &, int);	//assign port and automatically obtain address
	


public:
	int sd;				//socket descriptor
	Mysocket(sockaddr_in & , int); //constructor
	void Bind(sockaddr_in &);		//Bind host to socket
	void Close();
	void Recieve(sockaddr_in & , char * &);	//Recieve from a client
	void Send(sockaddr_in & , char * &);
	void Connect(sockaddr_in & ,char * &,int);

};

Mysocket::Mysocket(sockaddr_in & host , int port)
{
	WinConnect();
	sd = socket(AF_INET, SOCK_DGRAM, 0);	//creating socket and setting the descriptor

	if (sd == INVALID_SOCKET)
		{
			cout<< "ERROR: Could Not Create Socket."<<endl;
			WSACleanup();
			exit(0);
		}
	GetInfo(host , port);		//assign port and automatically obtain address

	
}

void Mysocket::WinConnect()
{
WSADATA w;
	if (WSAStartup(0x0101, &w) != 0)
		{
			cout<< "ERROR: Could Not Open Windows connection."<<endl;
			exit(0);
		}

}
void Mysocket::GetInfo(sockaddr_in & host , int port)
{
	memset(&host, 0, sizeof(host));  //clears out our host struct

	host.sin_family = AF_INET;		//set host's family.. *as socket*
	host.sin_port = htons(port);	// set server's port number

	char * host_name = new char[50];

	gethostname(host_name, strlen(host_name));  //obtains computer's hostname

	hostent * hp;			//hp is a struct of type hostent which contains address returned by gethostbyname()
    hp = gethostbyname(host_name);
	
    if (hp == NULL)
    {
        cout<<"ERROR: Could Not Get Host Name."<<endl;
        closesocket(sd);
        WSACleanup();
        exit(0);
    }
	cout<<"Host Name is: "<<host_name<<endl;

    host.sin_addr.S_un.S_un_b.s_b1 = hp->h_addr_list[0][0]; //assigning address
    host.sin_addr.S_un.S_un_b.s_b2 = hp->h_addr_list[0][1];
    host.sin_addr.S_un.S_un_b.s_b3 = hp->h_addr_list[0][2];
    host.sin_addr.S_un.S_un_b.s_b4 = hp->h_addr_list[0][3];

	cout<<"Server Adress is: ";
	cout<<static_cast<int>(host.sin_addr.S_un.S_un_b.s_b1)<<".";
	cout<<static_cast<int>(host.sin_addr.S_un.S_un_b.s_b2)<<".";
	cout<<static_cast<int>(host.sin_addr.S_un.S_un_b.s_b3)<<".";
	cout<<static_cast<int>(host.sin_addr.S_un.S_un_b.s_b4)<<endl;
}

void Mysocket::Bind(sockaddr_in & host)
{
	//bind server adress to the socket created
	if(bind(sd, (struct sockaddr *)&host, sizeof(struct sockaddr_in)) == -1)
	{
		cout<< "ERROR: Could Not Bind To Socket."<<endl;
		WSACleanup();
		closesocket(sd);
		exit(0);
	}

}
void Mysocket::Close()
{
		cout<< "Closing Socket with Descriptor "<<sd<<endl;
		WSACleanup();
		closesocket(sd);
		exit(0);
}
void Mysocket::Recieve(sockaddr_in & client, char * & buffer)
{
	cout<<"Listening on Socket "<<sd<<"...."<<endl;
		listen(sd,1);   //listen to created socket for connection (1 connection max)
		

		accept(sd,0,0); //accept connection on socket
		
		char* temp = new char[25000];
		int clen = sizeof (sockaddr_in);
		int size = 	recvfrom(sd,temp,strlen(temp),0,(struct sockaddr *) &client,&clen);	//get recieved input and put in temp
		
		for (int i = 0 ; i <size ; i++)
			buffer[i] = temp[i];

		buffer[i] = NULL;
		
		
		delete temp;
		
}
void Mysocket::Send(sockaddr_in & host , char * & buffer)
{
	if(	sendto(sd, buffer, (int)strlen(buffer),0, (struct sockaddr *)&host, sizeof(struct sockaddr_in)) != -1)
		{
			cout<<"Message Sent Successfully"<<endl;
		}
	else
	{
		cout<<"ERROR: Message Send Failed"<<endl;
	}
}
void Mysocket::Connect(sockaddr_in & sendhost , char * & host_name , int port )
{
	
	memset(&sendhost, 0, sizeof(sendhost));  //clears out our host struct

	sendhost.sin_family = AF_INET;		//set host's family.. *as socket*
	sendhost.sin_port = htons(port);		// set server's port number
	
	hostent * hp;			//hp is a struct of type hostent which contains address returned by gethostbyname()
    hp = gethostbyname(host_name);
	
    if (hp == NULL)
    {
        cout<<"ERROR: Could Not Get Host Name."<<endl;
        closesocket(sd);
        WSACleanup();
        exit(0);
    }

	
    sendhost.sin_addr.S_un.S_un_b.s_b1 = hp->h_addr_list[0][0]; //assigning address
    sendhost.sin_addr.S_un.S_un_b.s_b2 = hp->h_addr_list[0][1];
    sendhost.sin_addr.S_un.S_un_b.s_b3 = hp->h_addr_list[0][2];
    sendhost.sin_addr.S_un.S_un_b.s_b4 = hp->h_addr_list[0][3];




if (::connect(sd,(struct sockaddr *)&sendhost, sizeof (struct sockaddr_in))) {
		cout<< "ERROR: Cannot Connect to Host"<<endl;
		WSACleanup();
		closesocket(sd);
		exit(0);
  }


}
#endif
hbe02 is offline   Reply With Quote
Old May 22nd, 2006, 5:21 PM   #12
jayme
Professional Programmer
 
jayme's Avatar
 
Join Date: Nov 2005
Location: Canada
Posts: 495
Rep Power: 0 jayme is an unknown quantity at this point
Send a message via MSN to jayme
I would either use the windows messages or create a thread. I find creating threads causes more lag than I want so I usually go with windows messages.

EDIT: I suggest removing those extra functions that are un-needed.

void Mysocket::WinConnect()
{
WSADATA w;
	if (WSAStartup(0x0101, &w) != 0)
		{
			cout<< "ERROR: Could Not Open Windows connection."<<endl;
			exit(0);
		}

}
This is just a waste of space. WinConnect is called inside the constructor, and you will never have to use WinConnect() in your code so why even create a function for it? Same goes for your close() function. They just help clutter up your code.
__________________

Quote:
Originally Posted by Mohamed Jihad
Durka durka!
Due to incorrect calculations during the middle ages, our calendar actually begins a few years after Jesus' birth. Thus the real 6/6/6 happened a few years back. The world already ended and you missed it.

Download Code::Blocks now!
jayme is offline   Reply With Quote
Old May 22nd, 2006, 5:26 PM   #13
hbe02
Hobbyist Programmer
 
hbe02's Avatar
 
Join Date: Mar 2006
Location: Lebanon
Posts: 148
Rep Power: 3 hbe02 is on a distinguished road
is that an answer to my question about running some code in parallel to listening to the socket..? well i dont really know anything about windows messages... what are they.. ? how can they be used..? why are they used..?so do i just google them and learn..?
thanks..
hbe02 is offline   Reply With Quote
Old May 22nd, 2006, 5:31 PM   #14
jayme
Professional Programmer
 
jayme's Avatar
 
Join Date: Nov 2005
Location: Canada
Posts: 495
Rep Power: 0 jayme is an unknown quantity at this point
Send a message via MSN to jayme
You could also have a switch statement so that whatever happens(send, receive, user connects), the specific functions are given a number and the program waits for a function to happen then an int is given a number which deals with the specific function inside a switch statement.

Try googling "C++ message pump" for more information on windows messages.
__________________

Quote:
Originally Posted by Mohamed Jihad
Durka durka!
Due to incorrect calculations during the middle ages, our calendar actually begins a few years after Jesus' birth. Thus the real 6/6/6 happened a few years back. The world already ended and you missed it.

Download Code::Blocks now!
jayme is offline   Reply With Quote
Old May 22nd, 2006, 5:54 PM   #15
hbe02
Hobbyist Programmer
 
hbe02's Avatar
 
Join Date: Mar 2006
Location: Lebanon
Posts: 148
Rep Power: 3 hbe02 is on a distinguished road
Most of the google links lead to message pumps that deal with MFC functions like CWinThread::Run() which runs certain code when a message is recieved.. and CWinThread::OnIdle() which runs background code when no messages are recieved..
so as to compare with the counting example i gave..
CWinThread::Run() would listen to the socket, awaiting data.. and when this is idle , i.e no data is recieved i can count form 1 to infinity in the CWinThread::OnIdle() function..
is this right.. ? is this what im looking for..? i think it has more to do with GUI's im just looking for a very simple "message pumping" technique..

P.S: No comments on my socket class??
hbe02 is offline   Reply With Quote
Old May 22nd, 2006, 6:07 PM   #16
hbe02
Hobbyist Programmer
 
hbe02's Avatar
 
Join Date: Mar 2006
Location: Lebanon
Posts: 148
Rep Power: 3 hbe02 is on a distinguished road
Quote:
: I suggest removing those extra functions that are un-needed.
The link where i learnt sockets programming said :
Quote:
Before calling any socket functions, it is necessary to first open the Windows connection. This is done with the WSAStartup function.
So why did they say that if i can use sockets without salling the WSAStartup..?
Wont i need the close function to safely close the socket? or when u terminate the program the socket is safely closed automatically.. like a destructor type of thing?
hbe02 is offline   Reply With Quote
Old May 22nd, 2006, 6:07 PM   #17
nnxion
Programming Guru
 
nnxion's Avatar
 
Join Date: Jun 2005
Location: elemental plane
Posts: 1,429
Rep Power: 5 nnxion is on a distinguished road
Quote:
Originally Posted by hbe02
Please feel free to give any feedback or suggestions..
Have not looked at it extensively but I got to go to bed now (tired), Will help more tomorrow (if not solved by then).
#include <iostream>
#include <winsock2.h>

using namespace std;

class Mysocket
{

private:

	void WinConnect();
	void GetInfo(sockaddr_in &, int);

public:
	int sd;
	Mysocket(sockaddr_in & , int);
	void Bind(sockaddr_in &);
	void Close();
	void Recieve(sockaddr_in & , char * &);
	void Send(sockaddr_in & , char * &);
	void Connect(sockaddr_in & ,char * &,int);
};

Mysocket::Mysocket(sockaddr_in & host , int port)
{
	WinConnect();
	sd = socket(AF_INET, SOCK_DGRAM, 0);

	if (sd == INVALID_SOCKET)
	{
		cout << "ERROR: Could Not Create Socket." << endl;
		WSACleanup();
		exit(0);
	}
	GetInfo(host , port);
}

void Mysocket::WinConnect()
{
	WSADATA w;
	if (WSAStartup(0x0101, &w) != 0)
	{
		cout<< "ERROR: Could Not Open Windows connection."<<endl;
		exit(0);
	}
}

void Mysocket::GetInfo(sockaddr_in & host , int port)
{
	memset(&host, 0, sizeof(host));

	host.sin_family = AF_INET;
	host.sin_port = htons(port);

	char * host_name = new char[50];

	gethostname(host_name, strlen(host_name));

	hostent * hp;
	hp = gethostbyname(host_name);

	if (hp == NULL)
	{
		cout << "ERROR: Could Not Get Host Name." << endl;
		closesocket(sd);
		WSACleanup();
		exit(0);
	}
	cout<<"Host Name is: "<<host_name<<endl;

	host.sin_addr.S_un.S_un_b.s_b1 = hp->h_addr_list[0][0];
	host.sin_addr.S_un.S_un_b.s_b2 = hp->h_addr_list[0][1];
	host.sin_addr.S_un.S_un_b.s_b3 = hp->h_addr_list[0][2];
	host.sin_addr.S_un.S_un_b.s_b4 = hp->h_addr_list[0][3];

	cout<<"Server Adress is: ";
	cout<<static_cast<int>(host.sin_addr.S_un.S_un_b.s_b1)<<".";
	cout<<static_cast<int>(host.sin_addr.S_un.S_un_b.s_b2)<<".";
	cout<<static_cast<int>(host.sin_addr.S_un.S_un_b.s_b3)<<".";
	cout<<static_cast<int>(host.sin_addr.S_un.S_un_b.s_b4)<<endl;
}

void Mysocket::Bind(sockaddr_in & host)
{
	if(bind(sd, (struct sockaddr *)&host, sizeof(struct sockaddr_in)) == -1)
	{
		cout << "ERROR: Could Not Bind To Socket."<< endl;
		WSACleanup();
		closesocket(sd);
		exit(0);
	}
}

void Mysocket::Close()
{
	cout << "Closing Socket with Descriptor " << sd << endl;
	WSACleanup();
	closesocket(sd);
	exit(0);
}

void Mysocket::Recieve(sockaddr_in & client, char * & buffer)
{
	cout<<"Listening on Socket "<<sd<<"...."<<endl;
	listen(sd,1);

	accept(sd,0,0);

	char * temp = new char[25000];
	int clen = sizeof (sockaddr_in);
	int size = 	recvfrom(sd,temp,strlen(temp),0,(struct sockaddr *) &client,&clen);

	for (int i = 0 ; i <size ; i++)
		buffer[i] = temp[i];

	// i is out of scope here
	// did you mean NULL or the null character '\0'?
	buffer[i] = NULL;

	delete [] temp; // add [] ?
}

void Mysocket::Send(sockaddr_in & host , char * & buffer)
{
	if(	sendto(sd, buffer, (int)strlen(buffer),0, (struct sockaddr *)&host, sizeof(struct sockaddr_in)) != -1)
	{
		cout<<"Message Sent Successfully" << endl;
	}
	else
	{
		cout << "ERROR: Message Send Failed" << endl;
	}
}

void Mysocket::Connect(sockaddr_in & sendhost , char * & host_name , int port )
{
	memset(&sendhost, 0, sizeof(sendhost));

	sendhost.sin_family = AF_INET;
	sendhost.sin_port = htons(port);

	hostent * hp;
	hp = gethostbyname(host_name);

	if (hp == NULL)
	{
		cout << "ERROR: Could Not Get Host Name." << endl;
		closesocket(sd);
		WSACleanup();
		exit(0);
	}

	sendhost.sin_addr.S_un.S_un_b.s_b1 = hp->h_addr_list[0][0];
	sendhost.sin_addr.S_un.S_un_b.s_b2 = hp->h_addr_list[0][1];
	sendhost.sin_addr.S_un.S_un_b.s_b3 = hp->h_addr_list[0][2];
	sendhost.sin_addr.S_un.S_un_b.s_b4 = hp->h_addr_list[0][3];

	if (::connect(sd,(struct sockaddr *)&sendhost, sizeof (struct sockaddr_in)))
	{
		cout << "ERROR: Cannot Connect to Host" << endl;
		WSACleanup();
		closesocket(sd);
		exit(0);
	}
}
__________________
"Employ your time in improving yourself by other men's writings, so that you shall gain easily what others have labored hard for."
-- Socrates
nnxion is offline   Reply With Quote
Old May 22nd, 2006, 6:56 PM   #18
jayme
Professional Programmer
 
jayme's Avatar
 
Join Date: Nov 2005
Location: Canada
Posts: 495
Rep Power: 0 jayme is an unknown quantity at this point
Send a message via MSN to jayme
Quote:
Originally Posted by hbe02
The link where i learnt sockets programming said :

So why did they say that if i can use sockets without salling the WSAStartup..?
Wont i need the close function to safely close the socket? or when u terminate the program the socket is safely closed automatically.. like a destructor type of thing?
Yes, use wsastartup but don't wrap it in another function which is used to simply call the function. That's unnecessary and a waste of precious lines. Remove the WinConnect() function and move the contents of it into one of your more valuable functions, like the constructor for instance, since it will always be called with the constructor.

#include <iostream>
#include <winsock2.h>

using namespace std;

class Mysocket
{

private:

	void GetInfo(sockaddr_in &, int);

public:
	int sd;
	Mysocket(sockaddr_in & , int);
	void Bind(sockaddr_in &);
	void Close();
	void Recieve(sockaddr_in & , char * &);
	void Send(sockaddr_in & , char * &);
	void Connect(sockaddr_in & ,char * &,int);
};

Mysocket::Mysocket(sockaddr_in & host , int port)
{
	WSADATA w;
	if (WSAStartup(0x0101, &w) != 0)
	{
		cout<< "ERROR: Could Not Open Windows connection."<<endl;
		exit(0);
	}
	sd = socket(AF_INET, SOCK_DGRAM, 0);

	if (sd == INVALID_SOCKET)
	{
		cout << "ERROR: Could Not Create Socket." << endl;
		WSACleanup();
		exit(0);
	}
	GetInfo(host , port);
}

void Mysocket::GetInfo(sockaddr_in & host , int port)
{
	memset(&host, 0, sizeof(host));

	host.sin_family = AF_INET;
	host.sin_port = htons(port);

	char * host_name = new char[50];

	gethostname(host_name, strlen(host_name));

	hostent * hp;
	hp = gethostbyname(host_name);

	if (hp == NULL)
	{
		cout << "ERROR: Could Not Get Host Name." << endl;
		Close();
	}
	cout<<"Host Name is: "<<host_name<<endl;

	host.sin_addr.S_un.S_un_b.s_b1 = hp->h_addr_list[0][0];
	host.sin_addr.S_un.S_un_b.s_b2 = hp->h_addr_list[0][1];
	host.sin_addr.S_un.S_un_b.s_b3 = hp->h_addr_list[0][2];
	host.sin_addr.S_un.S_un_b.s_b4 = hp->h_addr_list[0][3];

	cout<<"Server Adress is: ";
	cout<<static_cast<int>(host.sin_addr.S_un.S_un_b.s_b1)<<".";
	cout<<static_cast<int>(host.sin_addr.S_un.S_un_b.s_b2)<<".";
	cout<<static_cast<int>(host.sin_addr.S_un.S_un_b.s_b3)<<".";
	cout<<static_cast<int>(host.sin_addr.S_un.S_un_b.s_b4)<<endl;
}

void Mysocket::Bind(sockaddr_in & host)
{
	if(bind(sd, (struct sockaddr *)&host, sizeof(struct sockaddr_in)) == -1)
	{
		cout << "ERROR: Could Not Bind To Socket."<< endl;
		Close();
	}
}

void Mysocket::Close()
{
	cout << "Closing Socket with Descriptor " << sd << endl;
	WSACleanup();
	closesocket(sd);
	exit(0);
}

void Mysocket::Recieve(sockaddr_in & client, char * & buffer)
{
	cout<<"Listening on Socket "<<sd<<"...."<<endl;
	listen(sd,1);

	accept(sd,0,0);

	char * temp = new char[25000];
	int clen = sizeof (sockaddr_in);
	int size = 	recvfrom(sd,temp,strlen(temp),0,(struct sockaddr *) &client,&clen);

	for (int i = 0 ; i <size ; i++){
		buffer[i] = temp[i];

	buffer[i] = '\0'; // A char array can't be "NULL"
	}
	
	delete [] temp;
}

void Mysocket::Send(sockaddr_in & host , char * & buffer)
{
	if(	sendto(sd, buffer, (int)strlen(buffer),0, (struct sockaddr *)&host, sizeof(struct sockaddr_in)) != -1)
	{
		cout<<"Message Sent Successfully" << endl;
	}
	else
	{
		cout << "ERROR: Message Send Failed" << endl;
	}
}

void Mysocket::Connect(sockaddr_in & sendhost , char * & host_name , int port )
{
	memset(&sendhost, 0, sizeof(sendhost));

	sendhost.sin_family = AF_INET;
	sendhost.sin_port = htons(port);

	hostent * hp;
	hp = gethostbyname(host_name);

	if (hp == NULL)
	{
		cout << "ERROR: Could Not Get Host Name." << endl;
		Close();
	}

	sendhost.sin_addr.S_un.S_un_b.s_b1 = hp->h_addr_list[0][0];
	sendhost.sin_addr.S_un.S_un_b.s_b2 = hp->h_addr_list[0][1];
	sendhost.sin_addr.S_un.S_un_b.s_b3 = hp->h_addr_list[0][2];
	sendhost.sin_addr.S_un.S_un_b.s_b4 = hp->h_addr_list[0][3];

	if (::connect(sd,(struct sockaddr *)&sendhost, sizeof (struct sockaddr_in)))
	{
		cout << "ERROR: Cannot Connect to Host" << endl;
		Close();
	}
}
This is a little better than what your previous code. The "NULLing" of your character array, removal of non-needed functions, and one of your for loops is now a block(it wasn't before and compilation had errors).
__________________

Quote:
Originally Posted by Mohamed Jihad
Durka durka!
Due to incorrect calculations during the middle ages, our calendar actually begins a few years after Jesus' birth. Thus the real 6/6/6 happened a few years back. The world already ended and you missed it.

Download Code::Blocks now!
jayme is offline   Reply With Quote
Old May 23rd, 2006, 3:29 AM   #19
hbe02
Hobbyist Programmer
 
hbe02's Avatar
 
Join Date: Mar 2006
Location: Lebanon
Posts: 148
Rep Power: 3 hbe02 is on a distinguished road
Smile

thanks for the feedback jayme.. regarding the NULL at the end of the array.. what i did was copy my (char* temp) to (char * buffer) in the for loop but i had to set the last array element of buffer to a NULL.. it works fine with me, i used to put '\0' but NULL never changed anything.. it did the job just as '\0'.
I know i should use strcpy but i will be using this class to copy ASCII code for images later on..
many of my collegeues tell me i throw alot of functions here and there.. but i do that just to make my main function shorter. the main function would call smaller functions to perform its dirty work instead of making my main function too long with code. in order to make it easier to debug and understand. and thats what i tried to do with my constructor.. on the other hand, i think your right about opening a windows connection, its just a simple little call and its a waste to put in its own function.
hbe02 is offline   Reply With Quote
Old May 23rd, 2006, 10:14 PM   #20
nindoja
Programmer
 
Join Date: Jun 2005
Posts: 92
Rep Power: 4 nindoja is on a distinguished road
bhe02: In regards to your other question, look up WSAEnumNetworkEvents and WSAEventSelect
nindoja is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 1:37 PM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC