/** * Fährt den Spcket Server bei einem Fehler runter. Dabei werden zuerst alle Subserver heruntergefahren die jeweiligen Socketverbindungen getrennt. * @param lsd Der jeweilige eindeutige Socketdeskriptor * @param error Fehlercode * @return Gibt eine 0 für erfolgreiches runterfahren aller Sockets zurück */ int shutDownServer(int lsd, int error){ server_shutdown = 1; //set shutdown flag printf("\r\nTCP Echoserver shutdown\r\n"); for(int i=0;i<MAX_SERVER;i++)// wakeup sleeping tasks { if((EchoServer[i].sd==-1) && (EchoServer[i].taskID!=-1)) { RTX_Wakeup(EchoServer[i].taskID); } } //wait until the subserver tasks have finished int result=0; while(result<10) { RTX_Sleep_Time(1000); if((EchoServer[0].finish) && (EchoServer[1].finish) && (EchoServer[2].finish)) { break; } result++; } //removing DK40 Task RTX_Delete_Task(dk40ID); RTX_Sleep_Time(100); if(lsd!=-1) { #ifdef TCPSERV_DEBUG printf("\r\nTCP Echoserver: Closing listening socket %d",lsd); #endif result = closesocket(lsd,&error); if(result == API_ERROR) { printf("\r\nTCPEchoServer: Socket close failed %d",error); } } printf("\r\nTCP Echoserver finished\r\n"); return 0; }
static void CgiCli_signal(uint32_t arg){ RTX_Wakeup(arg); }
/** * main() */ int main() { int lsd = -1; //listening socketdescriptor int asd = -1; //new socketdescriptor from accept int port = TM_PORT_ECHO; //default port int error = 0; int result; //int i; struct sockaddr_in addr; struct sockaddr_in claddr; char ClientIP[17]; int taskrdy = -1; initServer(); startDK40Task(); initSubServerTask(lsd,error); RTX_Sleep_Time(100); lsd = openListenSocket(lsd,error); #ifdef TCPSERV_DEBUG printf("\r\nTCP Echoserver: Öffnen einen Socket %d",lsd); #endif /** * Setzt den horchenden Socket auf Wiederverwendbar ein * @param lsd Den Socketdeskriptor des horchenden Sockets * @param error Fehlercode * @return (0) für erfolgreich, ungleich (0) für fehler */ result = setreuse(lsd,&error); #ifdef TCPSERV_DEBUG if(result == API_ERROR){ printf("\r\nTCP Echoserver: Set reuse failed %d",error); } #endif addr.sin_family = PF_INET; addr.sin_port = htons(port); //Konvertierung von Little Endian zu Big Endian addr.sin_addr.s_addr = 0L; result = bind(lsd,(struct sockaddr *)&addr,&error); if(result == API_ERROR){ printf("\r\nTCP Echoserver, Bind socket failed %d",error); shutDownServer(lsd,error); }//(result == API_ERROR) /* * Endlosschleife, horcht und baut Verbindungen auf */ while(1) { /** * listen */ result = listen(lsd, MAX_SERVER, &error); if(result == API_ERROR){ printf("\r\nTCP Echoserver, listen failed %d",error); shutDownServer(lsd,error); }//if(result == API_ERROR) /** * accept , establish a connection */ claddr.sin_family = PF_INET; claddr.sin_port = 0; //clear claddr.sin_addr.s_addr = 0L; //clear result = accept(lsd,(struct sockaddr *)&claddr,&error); if(result == API_ERROR){ printf("\r\nTCP Echoserver, accept failed %d",error); shutDownServer(lsd,error); }//if(result == API_ERROR) InetToAscii(&claddr.sin_addr.s_addr,ClientIP); #ifdef TCPSERV_DEBUG printf("\r\nTCP Echoserver: Connected with %s , Port %u\r\n",ClientIP,claddr.sin_port); #endif asd = result; cnt_connection++; #ifdef SERVER_SHUTDOWN_TEST if(cnt_connection>6L){ result = closesocket(asd,&error); if(result==API_ERROR){ printf("\r\nTCP Echoserver, socket close failed %d",error); } printf("\r\nTCP Echoserver: Shutdown test\r\n"); shutDownServer(lsd,error); }//if(cnt_connection>6L) #endif /** * Suche einer ruhenden Server Task */ taskrdy = Get_Free_Server_Task(); if(taskrdy == -1){ //no sleeping task found #ifdef TCPSERV_DEBUG printf("\r\nTCPserver: busy, refusing connection with %s , Port %u\r\n",ClientIP,claddr.sin_port); #endif closesocket(asd, &error); }//if(taskrdy == -1) else{ //insert the socket descriptor EchoServer[taskrdy].sd = asd; //and wakeup the sleeping server task result = RTX_Wakeup(EchoServer[taskrdy].taskID); if(result != 0){ printf("\r\nTCPserver: wakeup error\r\n"); closesocket(asd, &error); }//if(result != 0) else{ //a task is waked up and serves from now on this connection } }//elseif(taskrdy == -1) //no sleeping task found }//while(1) //do forever }