portTASK_FUNCTION( vBasicTcpServer, pvParameters ) { struct sockaddr_in server_addr; char *ptr, *termPtr; int nbytes; TcpServerTaskArgs *pTaskArgs = (TcpServerTaskArgs *) pvParameters; while ( !pTaskArgs->Flags.TerminateThread ) { // socket as a stream if ( (lSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) { break; } // Set up listner port memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_len = sizeof(server_addr); server_addr.sin_addr.s_addr = htonl(INADDR_ANY); // inet_addr(cServer); server_addr.sin_port = htons(pTaskArgs->PortNumber); server_addr.sin_family = AF_INET; // link it to the socket if ( bind(lSocket,(struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { //Error. Close the socket close(lSocket); break; } // begin to listen (this is a Non-blocking call; Accept call blocks it) if(listen(lSocket, 0) < 0) { close (lSocket); break; } memset(pTaskArgs->InBuffer, 0, sizeof(pTaskArgs->InBuffer)); ptr = &pTaskArgs->InBuffer[0]; totalBytes=0; nbytes = 10000; // listen socket timeout clientfd = accept(lSocket, NULL, NULL); // close listener 'cause it accepts another connections even though backlog = 0; close (lSocket); lSocket = -1; print_dbg ("TcpServer - connected\n"); // set how long to wait for a message (used in BLOCK'd recv mode) setsockopt(clientfd, SOL_SOCKET, SO_RCVTIMEO, (void*)&pTaskArgs->RcvTimeout, sizeof(pTaskArgs->RcvTimeout)); do { nbytes = recv(clientfd, ptr, sizeof(pTaskArgs->InBuffer) - totalBytes, MSG_DONTWAIT); // Is there anything to process? // NOTE: This is for non-BLOCK'd recv mode; BLOCK'd call returns 0 iff connection is closed. if ( nbytes > 0 ) { // look for message termination chars (CR/LF) termPtr = strstr (pTaskArgs->InBuffer, termStr); if (nbytes < maxBuffSize) { // buffer must be NULL terminated pTaskArgs->InBuffer[nbytes] = '\0'; // remove message termination string, if any if ( (termPtr = strstr (pTaskArgs->InBuffer, termStr)) != NULL ) *termPtr = '\0'; // this routine blocks until the message is processed ProcessRemoteMsg (pTaskArgs->InBuffer, pTaskArgs->OutBuffer); // monitor loss of connection if ( !connected(clientfd) ) break; // send reply to remote message send(clientfd, pTaskArgs->OutBuffer, strlen(pTaskArgs->OutBuffer), 0); // reset reception parameters ptr = &pTaskArgs->InBuffer[0]; } else { // message too large ; send error message sprintf(pTaskArgs->OutBuffer, "ERRS=Message exceeded %d-byte limit", pTaskArgs->maxBuffSize); //print_dbg ("TcpServer - sending\n"); send(clientfd, pTaskArgs->OutBuffer, strlen(pTaskArgs->OutBuffer), 0); // reset reception parameters ptr = &pTaskArgs->InBuffer[0]; } } } while ( connected(clientfd) ); print_dbg ("TcpServer - lost connection\n"); close(clientfd); clientfd = -1; vTaskDelay (500); }; close (lSocket); // Kill this task. vTaskDelete(NULL); }