// receive and process agent/server notifications DWORD rxClientThread(LPVOID arg) { char buffer[1024], msg[2048], * delim; int nBytes; struct socketDescriptor * sd = (struct socketDescriptor *) arg; SOCKET socket=sd->socket; msg[0]='\0'; addSocketDescriptorToClientList(sd); while(!sd->exit) { if (!sd->connected) { if (establishConnection(sd)) socket=sd->socket; else Sleep(10000); } else { nBytes=recv(sd->socket, buffer, sizeof(buffer-1), 0); if (nBytes==0) { // graceful close shutdownConnection(sd); } else if(nBytes==SOCKET_ERROR) { // forceful close if (WSAGetLastError()!=WSAECONNABORTED) { // an aborted connection error is normal on a half closed connection printErrorMsg("rxClientThread"); } shutdownConnection(sd); } else { // concatenate packets into a single carriage return terminated message // or process multiple carriage return terminated messages individually if (strlen(msg) + nBytes > sizeof(msg)) { // prevent an overrun msg[0]='\0'; } buffer[nBytes]='\0'; strcat(msg, buffer); while (delim=strstr(msg, "\r")) { *delim='\0'; processServerMsg(msg, sd); strcpy(msg, delim+1); } } } } CloseHandle(sd->hThread); sd->hThread=NULL; printq("rxClientThread exit host %s socket %d\n", sd->host, socket); ExitThread(0); }
// receive and process client commands DWORD rxServerThread(LPVOID arg) { struct socketDescriptor * sd = (struct socketDescriptor *) arg; char buffer[1024], msg[2048], * delim; int nBytes; LinkedList * l; SOCKET socket = sd->socket; msg[0]='\0'; while(1) { nBytes=recv(socket, buffer, sizeof(buffer-1), 0); buffer[nBytes]='\0'; if (nBytes==0 || nBytes==SOCKET_ERROR || sd->exit) { if (!sd->exit) { if (nBytes==SOCKET_ERROR) { printErrorMsg("rxServerThread"); closesocket(socket); sd->socket = INVALID_SOCKET; } else { // close the connection normally processClientDisconnect(sd); shutdownConnection(sd); } } sd->connected = FALSE; free((char *) sd->host); free((char *) sd->description); CloseHandle(sd->hThread); sd->hThread = NULL; printq("rxServerThread exit socket %d\n", socket); ExitThread(0); } else { // concatenate packets into a single carriage return terminated message // or process multiple carriage return terminated messages sequentially if (strlen(msg) + nBytes > sizeof(msg)) msg[0]='\0'; // prevent an overrun strcat(msg, buffer); while (delim=strstr(msg, "\r")) { *delim='\0'; processClientMsg(msg, sd); strcpy(msg, delim+1); } } } }
// shutdown server and clients void shutdownServer() { if (serverListenSd.exit || !serverList) return; serverListenSd.exit = TRUE; if (serverListenSd.socket != INVALID_SOCKET) { closesocket(serverListenSd.socket); serverListenSd.socket = INVALID_SOCKET; } LinkedList * l; struct socketDescriptor * sd; for (l=serverList->first(); l->isNotLast(); l=l->next()) { sd = (struct socketDescriptor *) l->get(); sd->exit = TRUE; shutdownConnection(sd); } }
int ServerConnection::handleReply(AAAMessage* rep) { unsigned int rep_id = rep->endtoendId; int reply_code = AAAMessageGetReplyCode(rep); DBG("received reply - id %d, reply code %d\n", rep_id, reply_code); string sess_link = ""; req_map_mut.lock(); DReqMap::iterator it = req_map.find(rep_id); if (it != req_map.end()) { sess_link = it->second.first; req_map.erase(it); } else { DBG("session link for reply not found\n"); } req_map_mut.unlock(); if (!sess_link.empty()) { DiameterReplyEvent* r_ev = new DiameterReplyEvent((unsigned int)rep->commandCode, (unsigned int)rep->applicationId, AAAMessageAVPs2AmArg(rep)); if (!AmSessionContainer::instance()->postEvent(sess_link, r_ev)) { DBG("unhandled reply\n"); } } else { DBG("no session-link for DIAMETER reply.\n"); } if ((reply_code == AAA_OUT_OF_SPACE) || reply_code >= AAA_PERMANENT_FAILURE_START) { WARN("critical or permanent failure Diameter error reply" " (code %d) received. Shutdown connection.\n", reply_code); shutdownConnection(); } return 0; }
//--------------------------------------------------------------------------- // protected //--------------------------------------------------------------------------- // thread body void NetThread::run() { if (settings->getOutputLog()) cout << "[" << name << "]" << " start thread...start run()" << endl << flush; // start thread runThread = true; // main loop while(runThread){ // set start time of main loop startTime = QDateTime::currentDateTime().toMSecsSinceEpoch(); //QThread::msleep(5); // 5 (ms) sleep QThread::msleep(threadSleepTime); // threadSleepTime (ms) sleep CONNECT_RESULT result_connect = connectToServer(); if (result_connect != CONNECT_SUCCEEDED){ if (result_connect == CONNECT_WAITED_COUNT){ continue; } if (result_connect == CONNECT_FAILED){ //cout << "[" << name << "]" << " connect Error: connectToServer()" << endl << flush; // error shutdownConnection(); emit networkError(true); //emit outputLogMessage(QTB_MSG_CONNECT_ERROR); continue; } if (result_connect == CONNECT_FAILED_RETRY){ if (settings->getOutputLog()) cout << "[" << name << "]" << " connect Error: connectToServer()" << endl << flush; // error runThread = false; break; } } // process header (send and receive) PROCESS_RESULT result_process = processForHeader(); if (result_process != PROCESS_SUCCEEDED){ if (result_process == PROCESS_RESTART){ // restart shutdownConnection(); QThread::sleep(2); emit networkError(true); continue; } if (result_process == PROCESS_NETWORK_ERROR){ // error if (settings->getOutputLog()) cout << "[" << name << "]" << " Network Error: processForHeader()" << endl << flush; // error shutdownConnection(); emit networkError(true); continue; } if (result_process == PROCESS_PASSWORD_ERROR){ // error if (settings->getOutputLog()) cout << "[" << name << "]" << " Password Error: processForHeader()" << endl << flush; // error shutdownConnection(); runThread = false; emit networkError(false); emit outputLogMessage(QTB_MSG_PASSWORD_ERROR); break; } if (result_process == PROCESS_CONNECT_ERROR){ // error if (settings->getOutputLog()) cout << "[" << name << "]" << " Connect Error: processForHeader()" << endl << flush; // error shutdownConnection(); runThread = false; emit networkError(false); emit outputLogMessage(QTB_MSG_ALREADY_CONNECT_ANOTHER_CLIENT); break; } if (result_process == PROCESS_VIDEO_MODE_ERROR){ // error if (settings->getOutputLog()) cout << "[" << name << "]" << " Connect Error: processForHeader()" << endl << flush; // error shutdownConnection(); runThread = false; emit networkError(false); emit outputLogMessage(QTB_MSG_NOTSUPPORT_VIDEO_MODE); break; } if (result_process == PROCESS_UNKNOWN_ERROR){ // error if (settings->getOutputLog()) cout << "[" << name << "]" << " Unkown Error: processForHeader()" << endl << flush; // error shutdownConnection(); runThread = false; emit networkError(false); emit outputLogMessage(QTB_MSG_UNKNOWN_ERROR); break; } } // transmit local buffer to device buffer TRANSMIT_RESULT result_transmit = transmitBuffer(); switch(result_transmit){ case TRANSMIT_SUCCEEDED: // Nothing to do break; case TRANSMIT_RESTART: // restart shutdownConnection(); QThread::sleep(2); emit networkError(true); continue; break; case TRANSMIT_NETWORK_ERROR: if (settings->getOutputLog()) cout << "[" << name << "]" << " Failed: transmitBuffer(): network error" << endl << flush; // error shutdownConnection(); emit networkError(true); continue; break; case TRANSMIT_DATASIZE_ERROR: if (settings->getOutputLog()) cout << "[" << name << "]" << " Failed: transmitBuffer(): data size" << endl << flush; // error break; case TRANSMIT_FAILED_PUT_BUFFER: if (settings->getOutputLog()) cout << "[" << name << "]" << " Failed: transmitBuffer(): put buffer." << endl << flush; // error break; case TRANSMIT_FAILED_TRANSMIT_DEVICE_BUFFER: if (settings->getOutputLog()) cout << "[" << name << "]" << " Failed: transmitBuffer(): transmit device buffer." << endl << flush; // error break; case TRANSMIT_FAILED_IMAGE_DRAW: if (settings->getOutputLog()) cout << "[" << name << "]" << " Failed: transmitBuffer(): image draw." << endl << flush; // error break; default: // error ABORT(); break; } } // disconnect shutdownConnection(); if (settings->getOutputLog()) cout << "[" << name << "]" << " stop thread...exit run()" << endl << flush; }
void rxClientThreadExit(struct socketDescriptor * sd) { sd->exit=TRUE; shutdownConnection(sd); }