Hi. I have written a small test socket program that uses a background thread that accepts tcp connections and adds them to a connection list that is accessed by main().
When a connection is opened, then later closed, recv() is called (see line highlighted in code below), which throws an exception stating that the socket is closed.
When I compile in Dev-C++ the exception thrown in the main() thread is caught in the background thread. -- Why is this??
When I compile in Visual Studio 6 the exception is caught in the main() thread as I expected.
I upgraded the Dev-c++ compiler from mingw 3.4.2 to 3.4.5, but the problem still exists.
Does anyone know why this is happening, and if there are any workarounds?
Thanks.
The file is shown following:
Note: the TcpServerSocket.accept() method returns a new open TcpClientObject. All member functions simply call a socket function using the handle stored in the object. Exceptions thrown are derived from std::exception, with what() implemented.
The 2 socket classes are in separate files included in the project during compilation.
#include <cstdlib>
#include <iostream>
#include <string>
#include <list>
#include <conio.h>
#include <stdio.h>
#include "../WindowsPorts/TcpClientSocket.h"
#include "../WindowsPorts/TcpServerSocket.h"
using namespace std;
list<TcpClientSocket*> skts;
bool abortProgram = false;
DWORD __stdcall acceptThread(void *_port){
int port = *(int*)_port;
try{
cout << "Listening on " << port << endl;
TcpServerSocket listenSocket(port);
while(1){
TcpClientSocket *acc = NULL;
try{
acc = listenSocket.accept();
}
catch(exception &x){
cout << "acceptThread" << " (inner loop) Caught Exception: " << x.what() << endl;
}
if(acc){
cout << "Accepted connection from " << acc->getHost() << ":" << acc->getPort() << endl;
skts.push_back(acc);
}
Sleep(1); // useless
}
}
catch(exception &x){
cout << "acceptThread" << " Caught Exception: " << x.what() << endl;
cout << "Listening Port Closed. Quitting Thread." << endl;
cin.get();
abortProgram = true;
Sleep(10000);
}
return 0;
}
int main(int argc, char *argv[]){
DWORD port = 12350;
if(argc == 2){
port = atoi(argv[1]);
}
try{
CreateThread(0, 0, acceptThread, &port, 0, 0);
TcpServerSocket listen(12300);
list<TcpClientSocket*>::iterator socketInUse = skts.begin();
while(!abortProgram){
Sleep(1);
char ch = 0;
if(kbhit()){
ch = getch();
if(ch == 27){
if(++socketInUse == skts.end()){
socketInUse = skts.begin();
}
if(skts.size() > 0 && socketInUse != skts.end()){
cout << "Data will be directed to " << (*socketInUse)->getHost() << " \r";
}
ch = 0;
}
else{
try{
if(skts.size() > 0 && socketInUse != skts.end()){
(*socketInUse)->send(&ch, 1);
}
}
catch(exception &x){
cout << "main" << " Caught Exception: " << x.what() << endl;
}
}
}
for(list<TcpClientSocket*>::iterator it = skts.begin(); it != skts.end(); it++){
try{
if((*it)->waitForData(10) == 1){ // got data, display it
char buff[1500];
// ########### the following line will throw the exception when the connection is closed (remotely)
unsigned int len = (*it)->recv(buff, sizeof(buff));
// cout << "read " << len << " bytes " << (len == 0) << endl;
if(len > 0)
cout << (*it)->getHost() << ": " << string(buff, len) << endl;
}
}
catch(exception &x){
cout << "main" << " Caught Exception: " << x.what() << endl;
cout << "Closing port" << endl;
bool reset = false;
if(socketInUse == it){
reset = true;
}
delete *it; // destroy object
skts.erase(it); // destroy reference
if(reset)
socketInUse = skts.end();
break;
}
catch(...){
cout << "main" << " Unhandled Exception" << endl;
cout << "Closing port" << endl;
bool reset = false;
if(socketInUse == it){
reset = true;
}
delete *it; // destroy object
skts.erase(it); // destroy reference
if(reset)
socketInUse = skts.end();
break;
}
}
}
}
catch(exception &x){
cout << "main" << " Caught Exception: " << x.what() << endl;
}
catch(...){
cout << "main" << " Unhandled Exception" << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}