Archived

This topic is now archived and is closed to further replies.

ANSI2000

Socket Class related to class design and not Winsock.

Recommended Posts

ANSI2000    122
Actually it is a bit related. Posting here since some people do not look at Network Programming.... I have the following class
class Socket
{
public:

	Socket() { closed = false; };
	Socket(char *pIPAddress, int pPort, int pTimeOut = 0) throw(WinsockException);
	Socket(SOCKET pSocket) : sock(pSocket) {};
	~Socket() {};

	//void open(char *pIPAddress, int pPort, int pTimeOut = 0) throw(WinsockException);
	void write(char * pBuffer,int pBufferLength) throw(WinsockException);
	int read(char *pBuffer, int pBufferLength) throw(WinsockException);
	void closeSocket() throw(WinsockException);

	int getTimeOut() { return(timeOut); };

	/*
	Socket operator=(const Socket &rhs)
	{
		if(this == &rhs)
			return(*this);

		return(rhs);
	}
	*/

protected:

	void setTimeOut(int pTimeOut) { timeOut = pTimeOut; };

private:

	sockaddr_in  serverAddress;
	SOCKET sock;

	bool closed; // Flag preventing closing socket more then once.

	int timeOut;
};

// Required include files.
#include <winsock2.h>

// Application include files.
#include "socket.h"

Socket::Socket(char *pIPAddress, int pPort, int pTimeOut)
{
	int errorCode = 0;
	
	closed = false;
	
	setTimeOut(pTimeOut);

	if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)	
	{
		errorCode = WSAGetLastError();

		throw WinsockException("socket() failed.", errorCode);
	}

	int optionValue = getTimeOut();
	
	if((optionValue != 0) || (optionValue != NULL))
	{
		// Set the socket send timeout.
		if(setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&optionValue, sizeof(optionValue)) == SOCKET_ERROR)
		{
			errorCode = WSAGetLastError();

			throw WinsockException("setsockopt() failed.", errorCode);
		}	

		// Set the socket read timeout.
		if(setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&optionValue, sizeof(optionValue)) == SOCKET_ERROR)
		{
			errorCode = WSAGetLastError();

			throw WinsockException("setsockopt() failed.", errorCode);
		}
	}

	memset(&serverAddress, 0, sizeof(serverAddress));
    serverAddress.sin_family = AF_INET;  
    serverAddress.sin_addr.s_addr = inet_addr(pIPAddress);
    serverAddress.sin_port = htons(pPort);

	if(connect(sock, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) == SOCKET_ERROR)
    {
		errorCode = WSAGetLastError();

		throw WinsockException("connect() failed.", errorCode);
	}
}

/*
void Socket::open(char *pIPAddress, int pPort, int pTimeOut)
{
	int errorCode = 0;

	closed = false;
	
	setTimeOut(pTimeOut);

	if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)	
	{
		errorCode = WSAGetLastError();

		throw WinsockException("socket() failed.", errorCode);
	}

	int optionValue = getTimeOut();
	
	if((optionValue != 0) || (optionValue != NULL))
	{
		// Set the socket send timeout.
		if(setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&optionValue, sizeof(optionValue)) == SOCKET_ERROR)
		{
			errorCode = WSAGetLastError();

			throw WinsockException("setsockopt() failed.", errorCode);
		}	

		// Set the socket read timeout.
		if(setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&optionValue, sizeof(optionValue)) == SOCKET_ERROR)
		{
			errorCode = WSAGetLastError();

			throw WinsockException("setsockopt() failed.", errorCode);
		}
	}

	memset(&serverAddress, 0, sizeof(serverAddress));
    serverAddress.sin_family = AF_INET;  
    serverAddress.sin_addr.s_addr = inet_addr(pIPAddress);
    serverAddress.sin_port = htons(pPort);

	if(connect(sock, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) == SOCKET_ERROR)
    {
		errorCode = WSAGetLastError();

		throw WinsockException("connect() failed.", errorCode);
	}
}
*/

void Socket::write(char * pBuffer,int pBufferLength)
{
	int errorCode = 0;
	int bytesSent = 0;

	bytesSent = send(sock, pBuffer, pBufferLength, 0);

	if(bytesSent == SOCKET_ERROR)
	{
		errorCode = WSAGetLastError();
		
		throw WinsockException("send() failed.", errorCode);	
	}	
}

int Socket::read(char *pBuffer, int pBufferLength)
{
	int errorCode = 0;
	
	char *buffer = new char[pBufferLength];
	int bytesReceived = 0;
	
	bytesReceived = recv(sock, buffer, pBufferLength, 0);
	
	if((bytesReceived == SOCKET_ERROR) || (bytesReceived == 0)) 
	{
		errorCode = WSAGetLastError();
		
		throw WinsockException("recv() failed.", errorCode);	
	}

	memcpy(pBuffer, buffer, bytesReceived);

	return(bytesReceived);
}

void Socket::closeSocket()
{
	int errorCode = 0;
/*
	if(shutdown(sock, SD_BOTH) == SOCKET_ERROR)
	{
		errorCode = WSAGetLastError();

		sock = NULL;

		throw WinsockException("shutdown() failed.", errorCode);	
	}
*/

	if(!closed)
		if(closesocket(sock) == SOCKET_ERROR)
		{
			errorCode = WSAGetLastError();

			sock = NULL;

			throw WinsockException("closesocket() failed.", errorCode);	
		}

	closed = true;
		
	//shutdown(sock, SD_BOTH);
	//closesocket(sock);

	//sock = NULL;
}
 
Somewhere in my code... Socket sock1("255.255.255.255", 99999, 600000); Socket sock2; sock2 = sock1; sock2.write(...); The above should make a shallow copy of the SOCKET handle and the sockaddr_in structure right? Now when I call sock2.closeSocket(); This should free the socket handle and resources right? Is this done for both sock1 and sock2? I want it to work that way. So if I close one or the other they both get freed, if you know what I mean... Am doing this is because I must have a constant connection. I implement it by having 3 threads. One thread manages the connection and the other 2 are used for sending and receiving data respectivly.

Share this post


Link to post
Share on other sites