Ich experimentiere immer noch mit Netzwerkprogrammierung (ist spannend). Dabei habe ich festgestellt, dass ich zumindest auf der Clientseite eine Zeitüberwachung benötige. So wie ich das brauche, wird das in meinen Büchern nicht erwähnt.
Um auch längere Texte (text/plain), die sich über mehrere Sendeblöcke erstrecken können, habe ich die read_line.c verwendet. Damit ist zumindest das Abarbeiten der HTTP-Header recht einfach. Eingebaut habe ich das in folgendem Programmabschnitt (Problemstelle mit <<<< markiert):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | int send_request( char * sbuf ) { int sock_fd; FILE * fp; char * buffer = malloc( BUF ); struct sockaddr_in address; int n; char * cp = NULL; int content_length; int file_type; if( (sock_fd = socket( AF_INET, SOCK_STREAM, 0 )) > 0 ) printf( "Socket wurde angelegt\n" ); address.sin_family = AF_INET; address.sin_port = htons( server_port ); inet_aton( serveraddr, &address.sin_addr ); if( connect( sock_fd, (struct sockaddr*)&address, sizeof( address ) ) == 0 ) { printf( "Verbindung mit dem Server (%s) hergestellt\n", inet_ntoa( address.sin_addr ) ); } else { printf( "Keine Verbindung\n" ); close( sock_fd ); return -1; } send( sock_fd, sbuf, strlen( sbuf ), 0 ); content_length = 0; file_type = 0; while( 1 ) { n = readLine( sock_fd, buffer, BUF ); if( n < 0 ) { printf( "Read error!\n" ); return -1; } if( n == 0 ) { printf( "empty\n" ); break; } cp = buffer; if( *cp == '\r' && *(cp+1) == '\n') break; printf( "> %s", buffer ); if( strncmp( buffer, "Content-Length: ", 16 ) == 0 ) { cp += 16; content_length = atoi( cp ); continue; } if( strncmp( buffer, "Content-Type: image/png", 23 ) == 0 ) { file_type = 1; continue; } if( strncmp( buffer, "Content-Type: text/plain", 24 ) == 0 ) { file_type = 2; continue; } } if( file_type == 1 && content_length > 0 ) { if( (fp = fopen( "tmpthumb.png", "wb" )) ) { while( content_length > 0 ) { n = recv( sock_fd, buffer, BUF, 0 ); if( n > 0 ) { fwrite( buffer, n, 1, fp ); content_length -= n; } else { break; } } fclose( fp ); } } if( file_type == 2 && content_length > 0 ) { while( content_length > 0 ) { n = readLine( sock_fd, buffer, BUF ); // <<<< if( n < 0 ) { printf( "Read error!\n" ); return -1; } if( n == 0 ) { break; } printf( "%s", buffer ); content_length -= n; } } close( sock_fd ); return 0; } |
Das Problem entsteht nun, wenn der Server abstürzt, beendet wird oder eine falsche Länge angegeben hat. In meinem Fall war die Länge sogar richtig, aber es wurde ein zusätzliches Nullbyte angehängt. Daraufhin wartet die verlinkte Fremdfunktion bis in alle Ewigkeit auf die Sequenz "\r\n", die aber nicht mehr kommt.
Wie kann ich aus der Nummer raus kommen? Meine erste Idee war ein Timer. Aber was sollte der auslösen? Es ist ja alles der selbe Prozess. Der soll sich ja nicht komplett selbst abwürgen.