Click here to Skip to main content
15,887,364 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have written the below class but my guide told me to add an exception class like
"MySocketClient.h" and added all these throw statements.
I don't know how to write the exception class,can you please write the pseudo code for exception class.
C++
//---------------------------------------------------------------------------


#pragma hdrstop

#include "MySocketClient.h"

MySocketClient::MySocketClient() throw(SocketException){
	WSAData data;
	InitializeCriticalSection(§_);
	if(WSAStartup(MAKEWORD(2,2),&data)!=0){
		throw SocketException("Cant load WinSock library");
	}
	connected_=false;
}
//-----------------------------------------------------------------------------

MySocketClient::~MySocketClient(){
	WSACleanup();
}
//-----------------------------------------------------------------------------

void MySocketClient::receive(void){
	char recBuf[1024];
	while(1){
		EnterCriticalSection(§_);
		memset(recBuf,0,1024);
		int recLen=recv(sock_,recBuf,1024,0);
		if(recLen==0){
			onDisconnect(sock_);
			connected_=false;
			break;
		}else if(recLen<0){
			connected_=false;
			onConnectionError(sock_);
			break;
		}else{
			onReceive(sock_,recBuf,recLen);
		}
		LeaveCriticalSection(§_);
	}
}
//------------------------------------------------------------------------------
void MySocketClient::sendData(char *sendBuf,int sendLen) throw(SocketException){
	onSendData(sendBuf,sendLen);
	if(send(sock_,sendBuf,sendLen,0)<0){
		onConnectionError(sock_);
	}
	Sleep(200);
}*191#
//------------------------------------------------------------------------------
void MySocketClient::Connect(string hostname,unsigned short port) throw(SocketException){
	sock_=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	if(sock_==INVALID_SOCKET){
		throw SocketException("Cant create socket");
	}
	HOSTENT *host=gethostbyname(hostname.c_str());
	if(host==NULL){
		throw SocketException("Cant resolve host");
	}
	addr_.sin_family=AF_INET;
	addr_.sin_port=htons(port);
	addr_.sin_addr.S_un.S_addr=*(unsigned long*)host->h_addr_list[0];
	if(connect(sock_,(sockaddr*)&addr_,sizeof(sockaddr))==SOCKET_ERROR){
		throw SocketException("Connect Error");
	}
	DWORD dwThreadId;
	threadHandle_=CreateThread(NULL,0,startReceive,this,0,&dwThreadId);
	if(threadHandle_==NULL){
		connected_=false;
		shutdown(sock_,SD_BOTH);
		closesocket(sock_);
		throw SocketException("Receive thread create error");
	}
	connected_=true;
	onConnect(sock_);
}
//------------------------------------------------------------------------------



void MySocketClient::Disconnect(void){
	TerminateThread(threadHandle_,0);
	shutdown(sock_,SD_BOTH);
	closesocket(sock_);
}

		//Virtual functions
void MySocketClient::onReceive(SOCKET sock,char *recBuf,int recLen) throw(SocketException){
}

void MySocketClient::onDisconnect(SOCKET sock){
}

void MySocketClient::onConnectionError(SOCKET sock){
}

void MySocketClient::onSendData(char *sendBuf,int sendLen){

}

void MySocketClient::onConnect(SOCKET sock){
}
#pragma package(smart_init)
Posted

1 solution

A simple way to clarify the requirements of your exception class, is to look at each throw statement, and imagine it were a return statement instead.

In this case, all throw statements look the same: they "return" an object of a class called SocketException, and initialize it with a single argument of type const char*.

I haven't tried it but I believe the most simple solution would be:
C++
typedef const char* SocketException;

I. e. rather than define a new class, you use a pre-existing type. However, this could be problematic if you have more than one Exception type based on the same pre-existing type, because then you wouldn't be able to distinguish between the two types of errors.

So the next best solution would be:
C++
struct SocketException {
   const char* message;
   SocketException(const char* text) {
      message = text;
   }
};

Whether you make it a struct or a class doesn't matter, but if in the above example your member variable message were declared private, you'd need to add an accessor function as well.

Even better would be a constructor that doesn't simply copy a pointer, but creates a copy of the string. That would allow you to throw an exception with a constructed message that is stored in a temporary variable:
C++
#include <string>
class SocketException {
public:
   std::string message;
   SocketException(const char* text) {
      message = text;
   }
};


void foo() throw SocketException {
   char buffer[30]; // Accessing this with a pointer after leaving the function is an error!
   static int count = 0;
   sprintf(buffer, "foo called %d times!", count);
   ++count;
   throw SocketException(buffer);
}

Note that the SocketException object will be constructed before leaving the function, i. e. while buffer can still be accessed safely. If you would store only the pointer, accessing the message would cause a run-time error.
 
Share this answer
 
Comments
fjdiewornncalwe 12-Oct-12 10:05am    
+5. Excellent explanation.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900