Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
tomery11 committed Jan 15, 2019
2 parents 36050f0 + 28257fe commit b4f2e91
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 107 deletions.
153 changes: 58 additions & 95 deletions MyParallelServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,35 +11,34 @@
using namespace std;


/*
//run in a thread, talk to clients.
void *clientTalkThreadFunc(void *serverData) {
try {
//serverData is of type ServerData
struct ServerData *serverData1;
serverData1 = (struct ServerData *) serverData;

//little server threads: run in a thread, talk to clients.
void *clientTalkThreadFunc(void *talkingData) {
try {
//TalkingData is of type TalkingData
TalkingData *talkingData1;
talkingData1 = (TalkingData *) talkingData;
//talk to the client
serverData1->clientHandler->handleClient(serverData1->newSocket);//todo give client the input
talkingData1->clientHandler->handleClient(talkingData1->newSocket);
close(talkingData1->newSocket);
} catch (const char *exception) {
printf("%s",exception);
}
}

//listen and accept, give timeout of time
void listenAccept(int time, struct ServerData *serverData1) {
int MyParallelServer::listenAccept(int time, struct ServerData *serverData1) {
int l = 0;
l = listen(serverData1->socketDescriptor, 5);
if (l < 0) {
throw "server listen failed";
}

struct sockaddr_in client;
sockaddr_in client;
socklen_t clilen = sizeof(client);

timeval timeout;
timeout.tv_sec = 10;
timeout.tv_sec = time;
timeout.tv_usec = 0;

setsockopt(serverData1->socketDescriptor, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
Expand All @@ -48,99 +47,62 @@ void listenAccept(int time, struct ServerData *serverData1) {
//cout << "server try to accept" << endl;
int newSocket = accept(serverData1->socketDescriptor, (struct sockaddr*)&client, &clilen);
if (newSocket < 0) {
//in timeout end the thread
//in timeout end all the threads
if (errno == EWOULDBLOCK) {
cout << "timeout!" << endl;
break;
serverData1->parallelServer->stop();
} else { //in other error throw an exception
throw "accept failed";
}
}
serverData1->newSocket = newSocket;
return newSocket;
}
//wait for clients. for each client create a thread to talk with.

//main server thread: wait for clients. for each client create a thread to talk with.
void* parallelServerThreadFunc(void *serverData) {
int newSocket = 0;
vector<pthread_t> *threads;
vector<pthread_t> threads;
pthread_t threadID;
vector<TalkingData*> talkingStructs;
try {
//todo timeout in writing to the client
//serverData is of type ServerData
struct ServerData *serverData1;
serverData1 = (struct ServerData *) serverData;

//talk with client after client serially
//first client: listen for 10 seconds. set the new socket number for the thread
newSocket = serverData1->parallelServer->listenAccept(10, serverData1);
auto *talking1 = new TalkingData;
talkingStructs.push_back(talking1);
talking1->newSocket = newSocket;
talking1->clientHandler = serverData1->clientHandler;
//create a thread to talk with
int rc = pthread_create(&threadID, nullptr, parallelServerThreadFunc, (void *)&talking1);
if (rc) {
throw "unable to create thread";
}
threads.push_back(threadID);
//talk with the other clients: client after client serially. 1 second max to wait, end if timeout.
//cout << *serverData1->setStop << endl;
while (!(*serverData1->setStop)) {
//talk with a single client until get a stop sign
//listen for 1 second. set the new socket number for the thread
newSocket = serverData1->parallelServer->listenAccept(1, serverData1);
auto *talking = new TalkingData;
talkingStructs.push_back(talking);
talking->newSocket = newSocket;
talking->clientHandler = serverData1->clientHandler;
//create a thread for talking with the client
threads->push_back(nullptr);
int rc = pthread_create(&this->threadID, nullptr, parallelServerThreadFunc, (void *)serverData);
rc = pthread_create(&threadID, nullptr, parallelServerThreadFunc, (void *)&talking);
if (rc) {
throw "unable to create thread";
}
//cout << "server accepted" <<endl;
//handle the client
threads.push_back(threadID);
}
//end all the other threads
stopThreads(threads);
close(newSocket);
//sleep(1);
cout << "end of thread" << endl;
//serverData = NULL;
//return nullptr;
} catch (const char *exception) {
printf("%s",exception);
}
}
//run in the thread. talk with clients until get a stop sign.
//talk serially: continue talking to one client to the end before talk with next client.
void* 1parallelServerThreadFunc(void *serverData) {
int newSocket = 0;
try {
//todo timeout in writing to the client
//serverData is of type ServerData
struct ServerData *serverData1;
serverData1 = (struct ServerData *) serverData;
//talk with client after client serially
//cout << *serverData1->setStop << endl;
while (!(*serverData1->setStop)) {
//talk with a single client until get a stop sign
int l = 0;
l = listen(serverData1->socketDescriptor, 5);
if (l < 0) {
throw "server listen failed";
}
struct sockaddr_in client;
socklen_t clilen = sizeof(client);
timeval timeout;
timeout.tv_sec = 10;
timeout.tv_usec = 0;
setsockopt(serverData1->socketDescriptor, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
//accept
//cout << "server try to accept" << endl;
newSocket = accept(serverData1->socketDescriptor, (struct sockaddr*)&client, &clilen);
if (newSocket < 0) {
//in timeout end the thread
if (errno == EWOULDBLOCK) {
cout << "timeout!" << endl;
break;
} else { //in other error throw an exception
throw "accept failed";
}
}
//cout << "server accepted" <<endl;
//handle the client
serverData1->clientHandler->handleClient(newSocket);//todo give client the input
}
close(newSocket);
serverData1->parallelServer->stopThreads(&threads, &talkingStructs);
//end this one, and the whole parallel server
serverData1->parallelServer->stop();
//close(newSocket);-no need?
//sleep(1);
cout << "end of thread" << endl;
//serverData = NULL;
Expand Down Expand Up @@ -192,6 +154,7 @@ void MyParallelServer::open(int port, ClientHandler *clientHandler) {
serverData->socketDescriptor = socketDescriptor;
serverData->clientHandler = clientHandler;
serverData->setStop = &this->setStop;
serverData->parallelServer = this;

//start the thread
//int rc = pthread_create(&threadID, NULL, serverThreadFunc, (void *)serverData);
Expand All @@ -212,17 +175,14 @@ void MyParallelServer::stop() {
//stop server
this->setStop = true;
void *res;
//loop to close all the threads
int s;
for (auto it : this->threads) {
s = pthread_join(it, &res);
cout << "back from join" << endl;
if (s != 0) {
throw "error in join thread";
}
//free memory allocated by thread
//free(res);
//close the main thread
int s = pthread_join(threadID, &res);
cout << "back from join" << endl;
if (s != 0) {
throw "error in join thread";
}
//free memory allocated by thread
//free(res);
cout << "after free memory thread" << endl;
close(this->socketDescriptor);
delete this->serverData;
Expand All @@ -231,8 +191,8 @@ void MyParallelServer::stop() {
}


//stop the threads
void stopThreads(vector<pthread_t> *threads) {
//stop the little threads, clean memory of the big thread
void MyParallelServer::stopThreads(vector<pthread_t> *threads, vector<TalkingData*> *talkingStructs) {
cout << "stop threads" << endl;
void *res;
//loop to close all the threads
Expand All @@ -246,6 +206,9 @@ void stopThreads(vector<pthread_t> *threads) {
//free memory allocated by thread
//free(res);
}
//free memory of the big thread
for (auto it1 : *talkingStructs) {
delete(it1);
}
cout << "after free all but one thread" << endl;
}
*/
36 changes: 24 additions & 12 deletions MyParallelServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,39 @@
using namespace std;
using namespace server_side;

//struct for the little client talking threads
struct TalkingData {
int newSocket;
ClientHandler *clientHandler;
};

void *clientTalkThreadFunc(void *talkingData);
void* parallelServerThreadFunc(void *serverData);

class MyParallelServer : public Server {
pthread_t threadID;
//vector<pthread_t> threads;
bool setStop = false;
int socketDescriptor;
struct ServerData *serverData;
public:
void stopThreads(vector<pthread_t> *threads, vector<TalkingData*> *talkingStructs);
int listenAccept(int time, struct ServerData *serverData1);
virtual void open(int port, ClientHandler *clientHandler);
virtual void stop();

};

//the struct the server thread will get
struct ServerData {
MyParallelServer *parallelServer;
int port;
int socketDescriptor;
ClientHandler *clientHandler;
bool *setStop;
int newSocket;
};

class MyParallelServer : public Server {
pthread_t threadID;
vector<pthread_t> threads;
bool setStop = false;
int socketDescriptor;
struct ServerData *serverData;
/*public:
virtual void open(int port, ClientHandler *clientHandler);
virtual void stop();
*/
};


#endif //FLIGTSIMPROJ2_MYPARALLELSERVER_H

0 comments on commit b4f2e91

Please sign in to comment.