This repository has been archived on 2025-04-11. You can view files and clone it, but cannot push or open issues or pull requests.
csce313-mp4pinie64backup/dataserver.cpp

185 lines
5.4 KiB
C++
Raw Normal View History

2015-11-05 18:33:21 -06:00
/*
File: dataserver.C
Author: R. Bettati
Department of Computer Science
Texas A&M University
Date : 2012/07/16
Dataserver main program for MP3 in CSCE 313
*/
/*--------------------------------------------------------------------------*/
/* DEFINES */
/*--------------------------------------------------------------------------*/
/* -- (none) -- */
/*--------------------------------------------------------------------------*/
/* INCLUDES */
/*--------------------------------------------------------------------------*/
#include <cassert>
#include <cstring>
#include <sstream>
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include "reqchannel.h"
using namespace std;
/*--------------------------------------------------------------------------*/
/* DATA STRUCTURES */
/*--------------------------------------------------------------------------*/
/* -- (none) -- */
/*--------------------------------------------------------------------------*/
/* CONSTANTS */
/*--------------------------------------------------------------------------*/
/* -- (none) -- */
/*--------------------------------------------------------------------------*/
/* VARIABLES */
/*--------------------------------------------------------------------------*/
static int nthreads = 0;
/*--------------------------------------------------------------------------*/
/* FORWARDS */
/*--------------------------------------------------------------------------*/
void handle_process_loop(RequestChannel & _channel);
/*--------------------------------------------------------------------------*/
/* LOCAL FUNCTIONS -- SUPPORT FUNCTIONS */
/*--------------------------------------------------------------------------*/
string int2string(int number) {
stringstream ss;//create a stringstream
ss << number;//add number to the stream
return ss.str();//return a string with the contents of the stream
}
/*--------------------------------------------------------------------------*/
/* LOCAL FUNCTIONS -- THREAD FUNCTIONS */
/*--------------------------------------------------------------------------*/
void * handle_data_requests(void * args) {
RequestChannel * data_channel = (RequestChannel*)args;
// -- Handle client requests on this channel.
handle_process_loop(*data_channel);
// -- Client has quit. We remove channel.
delete data_channel;
}
/*--------------------------------------------------------------------------*/
/* LOCAL FUNCTIONS -- INDIVIDUAL REQUESTS */
/*--------------------------------------------------------------------------*/
void process_hello(RequestChannel & _channel, const string & _request) {
_channel.cwrite("hello to you too");
}
void process_data(RequestChannel & _channel, const string & _request) {
usleep(1000 + (rand() % 5000));
//_channel.cwrite("here comes data about " + _request.substr(4) + ": " + int2string(random() % 100));
_channel.cwrite(int2string(rand() % 100));
}
void process_newthread(RequestChannel & _channel, const string & _request) {
int error;
nthreads ++;
// -- Name new data channel
string new_channel_name = "data" + int2string(nthreads) + "_";
// cout << "new channel name = " << new_channel_name << endl;
// -- Pass new channel name back to client
_channel.cwrite(new_channel_name);
// -- Construct new data channel (pointer to be passed to thread function)
RequestChannel * data_channel = new RequestChannel(new_channel_name, RequestChannel::SERVER_SIDE);
// -- Create new thread to handle request channel
pthread_t thread_id;
// cout << "starting new thread " << nthreads << endl;
if (error = pthread_create(& thread_id, NULL, handle_data_requests, data_channel)) {
fprintf(stderr, "p_create failed: %s\n", strerror(error));
}
}
/*--------------------------------------------------------------------------*/
/* LOCAL FUNCTIONS -- THE PROCESS REQUEST LOOP */
/*--------------------------------------------------------------------------*/
void process_request(RequestChannel & _channel, const string & _request) {
if (_request.compare(0, 5, "hello") == 0) {
process_hello(_channel, _request);
}
else if (_request.compare(0, 4, "data") == 0) {
process_data(_channel, _request);
}
else if (_request.compare(0, 9, "newthread") == 0) {
process_newthread(_channel, _request);
}
else {
_channel.cwrite("unknown request");
}
}
void handle_process_loop(RequestChannel & _channel) {
for(;;) {
2015-11-13 10:02:10 -06:00
//cout << "Reading next request from channel (" << _channel.name() << ") ..." << flush;
2015-11-05 18:33:21 -06:00
string request = _channel.cread();
2015-11-13 10:02:10 -06:00
//cout << " done (" << _channel.name() << ")." << endl;
//cout << "New request is " << request << endl;
2015-11-05 18:33:21 -06:00
if (request.compare("quit") == 0) {
_channel.cwrite("bye");
usleep(10000); // give the other end a bit of time.
break; // break out of the loop;
}
process_request(_channel, request);
}
}
/*--------------------------------------------------------------------------*/
/* MAIN FUNCTION */
/*--------------------------------------------------------------------------*/
int main(int argc, char * argv[]) {
// cout << "Establishing control channel... " << flush;
RequestChannel control_channel("control", RequestChannel::SERVER_SIDE);
// cout << "done.\n" << flush;
handle_process_loop(control_channel);
}