probleme bei TCP/IP mit accept anweisung
-
Hallo,
habe ein kleines C Programm geschrieben das auf einem Beck Controller läuft der ein paar ein und ausgänge hat.
Dei normale I/O behandlung funktioniert nun soll als besonderes noch ein TCP/IP Server integriert werden - doch damit hab ich mega dolle Probleme und ich find auch nix im internet drüber
Also das problem ist nun das er ja immer bei der accept anweisung wartet bis er eine Verbindung bekommt - das soll er aber nicht denn er soll ja seine normale arbeite die I/O verknüpfung nicht vernachlässigen ...
Kann mir jemand helfen ???
Hier der jetzige code:
#pragma option -1 // 80186 Prozessorcode #include <DOS.H> #include "TCPIPAPI.H" #include "TCPIP.H" #include <stdio.h> #include "rtos.h" #include "hwapi.h" /*************************************************************************/ //defines /*************************************************************************/ #define TCPIPVECT 0xAC #define TM_PORT_ECHO 7 /*well known echo port*/ #define TM_TCPECHOBUF_SERVER_RECVSIZE 1024 /****************************************************************************/ //Buffers /****************************************************************************/ //static char recvbuf[TM_TCPECHOBUF_SERVER_RECVSIZE]; static char ClientIP[17]; static unsigned char val602; // the value written to address 0x602 // ---------------------------------------------------------------------------- //Get the inputs at E0 unsigned int getE0(void) { return inportb(0x600); } // ---------------------------------------------------------------------------- //Get the inputs at E1 unsigned int getE1(void) { unsigned int rslt; rslt=0x000F&inportb(0x603); // bits 0..3 if (!hal_read_pio(0)) rslt |= 0x0010; // bit 4 if (!hal_read_pio(1)) rslt |= 0x0020; // bit 5 if (!hal_read_pio(4)) rslt |= 0x0040; // bit 6 if (!hal_read_pio(3)) rslt |= 0x0080; // bit 7 return rslt; } // ---------------------------------------------------------------------------- // Check if the outputs have a overload int outputOverload(void) // ret 1 if overload on outputs A0 { return (0x01&inportb(0x602)); } // ---------------------------------------------------------------------------- // Check if a voltage is present for the output group int noOutputPowerAvail(void) // ret 1 if no power is connected { return (0x10&inportb(0x602)); } // ---------------------------------------------------------------------------- // Return the position of the switch int getSwitch(void) // return position of the switch { int rslt; disable(); // could be, we use several threads, so we must protect the // variable val602 outportb(0x602,val602|0x04); // set bit 2 rslt=inportb(0x602); outportb(0x602,val602); // reset bit 2 enable(); return rslt&0x0F; } // ---------------------------------------------------------------------------- // Set the color of the LED void setLED(int val) // set LED. 0: off, 1: green, 2: Red, 3: Yellow { disable(); val602 &= (~3); // first reset the bits 0 and 1 val602 |= val; outportb(0x602,val602); enable(); } // ---------------------------------------------------------------------------- // Gibt die einzelnen Bits als Byte an den Outport aus void makeOutPorts(int B0, int B1, int B2, int B3, int B4, int B5, int B6, int B7) { unsigned int X=0; X = B0 + (B1<<1) + (B2<<2) + (B3<<3) + (B4<<4) + (B5<<5) + (B6<<6) + (B7<<7); outportb(0x601,X); } // ---------------------------------------------------------------------------- // Hier gehts los .... int main(void) { // --------------------------------------------------------------------------- // ANFANGSDEKLARATIONEN // --------------------------------------------------------------------------- int E0_0, E0_1, E0_2, E0_3, E0_4, E0_5, E0_6, E0_7; int E1_0, E1_1, E1_2, E1_3, E1_4, E1_5, E1_6, E1_7; int M0_0 = 0, M0_1 = 0, M0_2 = 0, M0_3 = 0; //int M0_4 = 0, M0_5 = 0, M0_6 = 0, M0_7 = 0; //int M1_0 = 0, M1_1 = 0, M1_2 = 0, M1_3 = 0; //int M1_4 = 0, M1_5 = 0, M1_6 = 0, M1_7 = 0; int A0_0 = 0, A0_1 = 0, A0_2 = 0, A0_3 = 0; int A0_4 = 0, A0_5 = 0, A0_6 = 0, A0_7 = 0; int T00 = 0, T01 = 0; unsigned int WERT1, WERT2; int verz; struct sockaddr_in addr; struct sockaddr_in claddr; int sd; int asd; int established = 0; int retval; int error; // --------------------------------------------------------------------------- // PIO 0,1,3 und 4 als Eingang definieren pfe_enable_pio(0,1); pfe_enable_pio(1,1); pfe_enable_pio(3,1); pfe_enable_pio(4,1); // enable PCS6 und ALE pfe_enable_pcs(6); pfe_enable_bus(0xFFFF,1); // schreib und lesezugriff // alle Ausgaenge zuruecksetzen outportb(0x601,0); // TCP / IP ... printf("\r\nTCPserver, listening on port %d\r\n",TM_PORT_ECHO); #ifdef TCP_ECHO_SERVER_DEBUG printf("\r\nOpen socket"); #endif //API call open socket retval = opensocket( SOCK_STREAM, &error ); if(retval == API_ERROR) { printf("\r\nSocket open failed: %d",error); printf("\r\nTCPserver: Closing listening socket"); retval = closesocket( sd, &error ); } else { sd = retval; } /**********************************************************************/ //API-Call bind /**********************************************************************/ addr.sin_family = PF_INET; //convert your sending port to correct byte order retval = htons(TM_PORT_ECHO); addr.sin_port = retval; addr.sin_addr.s_addr = 0L; //call bind retval = bind( sd, (struct sockaddr *) &addr, &error ); if(retval == API_ERROR) { printf("\r\nTCPserver: Socket bind failed: %d",error); printf("\r\nTCPserver: Closing listening socket"); retval = closesocket( sd, &error ); } // Zykluszeit vom Drehschalter einlesen while (1>0) { if (getSwitch() > 0) { verz = getSwitch() * 10; } else { verz = 25; } RTX_Sleep_Time(verz); // ABBILD DER EINGAENGE BILDEN WERT1 = getE0(); E0_0 = WERT1&0x0001; E0_1 = WERT1&0x0002; E0_2 = WERT1&0x0004; E0_3 = WERT1&0x0008; E0_4 = WERT1&0x0010; E0_5 = WERT1&0x0020; E0_6 = WERT1&0x0040; E0_7 = WERT1&0x0080; WERT2 = getE1(); E1_0 = WERT2&0x0001; E1_1 = WERT2&0x0002; E1_2 = WERT2&0x0004; E1_3 = WERT2&0x0008; E1_4 = WERT2&0x0010; E1_5 = WERT2&0x0020; E1_6 = WERT2&0x0040; E1_7 = WERT2&0x0080; // --------------------------------------------------------------------------- // EINGANG E0.0 ODER E1.0 --> AUSGANG A0.0 // --------------------------------------------------------------------------- if ((E0_0 == 0x0001 || E1_0 == 0x0001) && M0_0 == 0) { if (A0_0 == 1) { A0_0 = 0; } else { A0_0 = 1; } M0_0 = 1; } // Taster entprellen ... if (M0_0 == 1 && T00 < 1000) { T00++; } // Freigabe der nächsten Bedienung nach loslassen des Tasters und // nach Entprellzeit if (E0_0 == 0 && E1_0 == 0 && M0_0 == 1 && T00 > 10) { M0_0 = 0; T00 = 0; } // ENDE // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- // EINGANG E0.1 ODER E1.1 --> AUSGANG A0.1 // --------------------------------------------------------------------------- if ((E0_1 == 0x0002 || E1_1 == 0x0002) && M0_1 == 0) { if (A0_1 == 1) { A0_1 = 0; } else { A0_1 = 1; } M0_1 = 1; } // Taster entprellen ... if (M0_1 == 1 && T01 < 1000) { T01++; } // Freigabe der nächsten Bedienung nach loslassen des Tasters und // nach Entprellzeit if (E1_1 == 0 && E0_1 == 0 && M0_1 == 1 && T01 > 10) { M0_1 = 0; T01 = 0; } // ENDE VON // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- // xxx // --------------------------------------------------------------------------- if (E0_2 == 0x0004 || E0_3 == 0x0008) { A0_2 = 1; } else { A0_2 = 0; } if (E0_3 == 0x0008 && E0_2 == 0) { A0_3 = 1; } else { A0_3 = 0; } // ENDE xxx // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- // xxx // --------------------------------------------------------------------------- if (E0_4 == 0x0010 || E0_5 == 0x0020 || E0_6 == 0x0040 || E0_7 == 0x0080) { A0_4 = 1; } else { A0_4 = 0; } if ((E0_5 == 0x0020 || E0_7 == 0x0080)&& E0_4 == 0 && E0_6 == 0) { A0_5 = 1; } else { A0_5 = 0; } // ENDE xxx // --------------------------------------------------------------------------- // ALLE AUSGAENGE AUF 0 SETZEN WENN SCHALTER AUF STOP IST if (getSwitch() == 0) { A0_0 = 0; A0_1 = 0; A0_2 = 0; A0_3 = 0; A0_4 = 0; A0_5 = 0; A0_6 = 0; A0_7 = 0; setLED(2); } else { setLED(1); } // AUSGAENGE SCHREIBEN makeOutPorts(A0_0,A0_1,A0_2,A0_3,A0_4,A0_5,A0_6,A0_7); // TCP IP ... if (!established); { /**********************************************************************/ //API-Call listen for connections /**********************************************************************/ printf("\r\nTCPserver: Listening for connection"); retval = 0; retval = listen( sd, 1, &error ); if(retval == API_ERROR) { printf("\r\nTCPserver: Socket listen failed: %d",error); printf("\r\nTCPserver: Closing listening socket"); retval = closesocket( sd, &error ); goto ENDE; } printf("\r\n -->%i, -->%i",retval,sd); /**********************************************************************/ //API-Call accept, establish a connection /**********************************************************************/ claddr.sin_family = PF_INET; claddr.sin_port = 0; claddr.sin_addr.s_addr = 0L; retval = accept( sd, (struct sockaddr *) &claddr, &error ); if(retval == API_ERROR) { printf("\r\nTCPserver: Socket accept failed: %d",error); printf("\r\nTCPserver: Closing listening socket"); retval = closesocket( sd, &error ); goto ENDE; } //save the new socketdescriptor asd = retval; established = 1; //get clients IP InetToAscii( (unsigned long *) &claddr.sin_addr.s_addr, (char *) ClientIP ); printf("\r\nTCPserver: Connected with %s , Port %u\r\n",ClientIP,claddr.sin_port); } if(established) { /*******************************************************************/ //Wait for incoming data from the client //To prevent a socketoverrun, we read all available data from the socket /*******************************************************************/ //recv char empf[1]; retval = recv( asd,empf, sizeof(empf),0, 20000L, &error ); //retval = 0; if(retval == API_ERROR) { established = 0; } else { if( retval > 0) //data received { /********************************/ //echo data back to the client /********************************/ //send retval = send( asd,empf, retval, 0, &error ); if(retval == API_ERROR) { established = 0; } }//if(retval > 0) //data received }//elseif(retval == API_ERROR) /*****************************************************************/ //Check, if there is more data available at the socket ? /*****************************************************************/ retval = GetWaitingBytes( asd, &error ); } ENDE: } } // ############################################################################
-
Hast Du Multitasking zur Verfuegung (ich sehe einen "rtos" header)? Dann ist es am einfachsten, fuer jede eingehende Verbindung einen Thread zu starten (musst Du bei einem Server eh). Mittels select() und Pruefung auf Lesbarkeit kannst Du den Listener-Socket auf eingehende Verbindungen pruefen. Ist der Listener lesbar, startest Du einen Thread und machst in dem Thread accept().
Eine andere Moeglichkeit, ist die Verwendung von Non-Blocking I/O. Das erreichst Du ueber setsockopt(). Du schaltest den Listener auf Nonblocking, dann kehrt accept() mit einem Fehlercode zurueck, wenn keine Verbindung anliegt.
Hoffe das hilft!
-
hmm hab nochnie mit threads gearbeitet
Gibts da ein gutes beispiel für ???Wie funktioniert das mit dem Nonblocking ????
-
ok das mit den threads funktioniert super
danke für den hinweis !