Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 #include <cstring>
00009 #include <sstream>
00010 #include <iostream>
00011 #include <fstream>
00012 #include <sys/socket.h>
00013 #include <sys/types.h>
00014 #include <sys/stat.h>
00015 #include <cerrno>
00016
00017 #include "worker.h"
00018 #include "cvUtils.h"
00019
00020 using namespace std;
00021
00022 Worker::Worker(void* lp)
00023 {
00024 message("Worker init");
00025 csock = (int*)lp;
00026 memset(recordBUFF,0,sizeof( recordBUFF ));
00027 authMessage = "cyberlab";
00028 authReply = "project";
00029
00030 }
00031
00039 Worker::~Worker()
00040 {
00041 remove(recvFile.getFullName().c_str());
00042 remove(sendFile.getFullName().c_str());
00043 delete csock;
00044 }
00045
00055 int Worker::parseARGS(char **args, char *line)
00056 {
00057 string theDelim = headers::delim + headers::end;
00058 int tmp=0;
00059 args[tmp] = strtok( line, theDelim.c_str());
00060 while( ( args[++tmp] = strtok( NULL, theDelim.c_str() ) ) != NULL );
00061 return tmp - 1;
00062 }
00063
00064
00082 void Worker::comm()
00083 {
00084 message("Worker is communicating");
00085 if (!auth()) {
00086 killConnection();
00087 return;
00088 }
00089
00090
00091 if (!intent()) {
00092 killConnection();
00093 return;
00094 }
00095 if (!receivefile()) {
00096 killConnection();
00097 return;
00098 }
00099 cout << "Starting detection of stuff" << endl;
00100 CvUtils det(recvFile.getFullName(),featureType,descriptorType);
00101 sendFile.initFromPath(det.detect());
00102 cout << "Done detecting stuff" << endl;
00103 if (!sendfile()) {
00104 killConnection();
00105 return;
00106 }
00107 cout << "Operations completed" << endl;
00108 killConnection();
00109 return;
00110 }
00111
00112
00113
00125 bool Worker::intent()
00126 {
00127 message("Intent filter");
00128 if(!receiveMessage()){
00129 return false;
00130 }
00131 message(header[0]);
00132 if (strcmp(header[0],headers::extract.c_str()) ) {
00133 message("Unknown client intent");
00134 message(header[0]);
00135 return false;
00136 }
00137 featureType = header[1];
00138 descriptorType = header[2];
00139 string sendmsg = headers::ok + headers::end;
00140 if (!sendMessage(sendmsg)) {
00141
00142 return false;
00143 }
00144 return true;
00145
00146 }
00147
00148
00163 bool Worker::auth()
00164 {
00165 message("Authenticating mechanism");
00166 if (!receiveMessage()) {
00167
00168 return false;
00169 }
00170 message(header[0]);
00171 if (strcmp(header[0],headers::authenticate.c_str()) ) {
00172 message("Wrong authentication header");
00173 message(authMessage.c_str());
00174 message(header[0]);
00175 return false;
00176 }
00177 message(header[1]);
00178 if ( ( authMessage.length() != strlen(header[1] ) )
00179 || strcmp(authMessage.c_str(),header[1] ) ) {
00180 message("Client authentication failure");
00181 return false;
00182 }
00183 string authmsg = headers::authenticate + headers::delim + authReply + headers::end;
00184 if (!sendMessage(authmsg)) {
00185
00186 return false;
00187 }
00188 message("Authentication successful");
00189 return true;
00190 }
00191
00192
00210 bool Worker::receivefile()
00211 {
00212 long fileSize;
00213 ofstream ofile;
00214 long receivedBytes = 0;
00215 if (!receiveMessage()) {
00216
00217 return false;
00218 }
00219 if (strcmp(header[0],headers::filecopy.c_str())) {
00220 cout << "Wrong file copy header" << endl;
00221 cout << header[0] << endl;
00222 return false;
00223 }
00224 message(header[1]);
00225
00226
00227
00228
00229
00230 recvFile.initFromPath(randomFilename(header[1]));
00231
00232 message(recvFile.getFullName().c_str());
00233
00234 message(header[2]);
00235 ss << header[2];
00236 ss >> fileSize;
00237
00238 ofile.open(recvFile.getFullName().c_str(), ios::out | ios::binary);
00239
00240 if (ofile.fail()) {
00241 cout << "Failed to open file. Error: " << errno << endl;
00242 ofile.close();
00243 return false;
00244 }
00245 string sendmsg = headers::ok + headers::end;
00246 if (!sendMessage(sendmsg)) {
00247
00248 return false;
00249 }
00250 cout << "FileSize: " << fileSize << endl;
00251 while(receivedBytes < fileSize){
00252 recordBUFF[0] = 0;
00253 rcv = recv(*csock, recordBUFF, sizeof( recordBUFF ),0);
00254 if (rcv < 0) {
00255 cout << "Error while receiving data. Error is " << errno << endl;
00256 ofile.close();
00257 return false;
00258 }
00259 if (rcv == 0)
00260 {
00261 message("Client dropped connection");
00262 ofile.close();
00263 return false;
00264 }
00265
00266 ofile.write(recordBUFF,rcv);
00267 receivedBytes = receivedBytes+rcv;
00268 }
00269 ofile.close();
00270 cout << "File receive operation complete!" << endl;
00271 return true;
00272 }
00273
00274
00291 bool Worker::sendfile()
00292 {
00293
00294 struct stat FileInfo;
00295 long fileSize;
00296
00297 ifstream infile;
00298 infile.open(sendFile.getFullName().c_str(), ios::in | ios::binary);
00299 if (infile.fail()) {
00300 cout << "Failed to open file. Error: " << errno << endl;
00301 infile.close();
00302 return false;
00303 }
00304
00305 if (stat(sendFile.getFullName().c_str(), &FileInfo) == 0) {
00306 fileSize = FileInfo.st_size;
00307 }
00308 ss << fileSize;
00309 string request = headers::filecopy + headers::delim + sendFile.name + headers::delim + ss.str() + headers::end;
00310 if (!sendMessage(request)) {
00311
00312 return false;
00313 }
00314 cout << request << endl;
00315 cout << "Sent: " << snt << " bytes" << endl;
00316 if (!receiveMessage()) {
00317
00318 return false;
00319 }
00320 cout << "Received: " << rcv << " bytes" << endl;
00321 message(header[0]);
00322 if (strcmp(header[0], headers::ok.c_str())) {
00323 cout << "Client did not send correct confirmation header" << endl;
00324 cout << header[0] << endl;
00325 return false;
00326 }
00327 cout << "Ready to send file!" << endl;
00328
00329 infile.seekg(0, ios::beg);
00330 while(!infile.eof()){
00331 infile.read(recordBUFF, sizeof( recordBUFF ));
00332 snt = send(*csock, recordBUFF, infile.gcount(),0);
00333
00334 if (snt < 0) {
00335
00336 cout << "Error during fileSend. Error: " << errno << endl;
00337 infile.close();
00338 return false;
00339 }
00340 if (snt == 0)
00341 {
00342 message("Client dropped connection");
00343 infile.close();
00344 return false;
00345 }
00346 }
00347 infile.close();
00348 cout << "File send operation complete!" << endl;
00349 return true;
00350 }
00351
00352
00363 void Worker::killConnection()
00364 {
00365 message( "Server closes connection to client" );
00366
00367 shutdown( *csock, 2 );
00368 close( *csock );
00369 }
00370
00379 bool Worker::sendMessage(string msg)
00380 {
00381 if (sizeof( msg ) > sizeof( recordBUFF) ) {
00382 cout << "Message too big for send buffer" << endl;
00383 return false;
00384 }
00385 strcpy(recordBUFF, msg.c_str());
00386 snt = send( *csock, recordBUFF, msg.size(), 0 );
00387 if (snt < 0) {
00388 cout << "Error sending message. Error is " << errno << endl;
00389 return false;
00390 }
00391 if (snt == 0) {
00392 cout << "Client closed connection" << endl;
00393 return false;
00394 }
00395 return true;
00396 }
00405 bool Worker::receiveMessage()
00406 {
00407 recordBUFF[0] = 0;
00408 rcv = recv(*csock, recordBUFF, sizeof( recordBUFF ), 0);
00409 if (rcv < 0) {
00410 cout << "Error receiving message. Error is " << errno << endl;
00411 return false;
00412 }
00413 if (rcv == 0) {
00414 cout << "Client closed connection" << endl;
00415 return false;
00416 }
00417 recordBUFF[rcv] = 0;
00418 int numParams = parseARGS(header, recordBUFF);
00419 if (!strcmp(header[numParams], headers::close.c_str())) {
00420 cout << "The client has closed the connection, no use continuing" << endl;
00421 return false;
00422 }
00423 return true;
00424 }
00432 void Worker::message(const char *msg)
00433 {
00434 cout << msg << endl;
00435 }
00436
00445 string Worker::randomFilename(string suffix)
00446 {
00447 char buffer[L_tmpnam];
00448 tmpnam(buffer);
00449 string tmpFile(buffer);
00450 return tmpFile+suffix;
00451 }