TCP Socket blockiert!



  • Hallo Leute,
    ich versuche mich grade mit Sockets...

    Ich habe folgendes vor.. ein TCP Client verbindet sich auf "diesen" Server und schickt ab und zu mal eine Nachricht.
    Das Funktioniert soweit. Nur habe ich nebenbei noch eine Timerfunktion die jede paar sekunden was machen soll.

    Ich habe es soweit geschafft dass die Timerfunktion beim Start läuft....
    Sobald aber sich der Client verbindet bleibt der beim

    recv(client_sock , client_message , 10 , 0);
    

    Ich habe schon versucht was mit select() zu machen aber leider ohne erfolg.
    Was kann ich machen und wo ist mein fehler? Danke im vorraus

    #include <time.h> 
    #include<stdio.h>
    #include<string.h>    //strlen
    #include<sys/socket.h>
    #include<arpa/inet.h> //inet_addr
    #include<unistd.h>    //write
    
    #include <fcntl.h>
    
    #include <sys/types.h>
    #include <sys/time.h>
    
    int socket_desc , client_sock , c , read_size;
    struct sockaddr_in server , client;
    char client_message[10];
    
    time_t timer;
    
    fd_set fds;
    volatile time_t timestamp;
    volatile time_t time1 = 21600; 
    volatile uint8_t temp_min, temp_sec; 
    
    
    void checktimer(){
        time_t now;
        time(&now);
        if(timestamp < now){
            timestamp = now + 2;
         printf("Sekunden seit 01.01.1970 00:00:00 Uhr: %d\n", now);
       // return 0;
    }
    } 
    
    void configSocket(){ 
        //Create socket
        socket_desc = socket(AF_INET , SOCK_STREAM , 0);
    
          //Create socket teil 2
        if (socket_desc == -1)
        {
            printf("Could not create socket");
        }
        puts("Socket created");
    
          // kill "Address already in use" error message
        int tr = 1;
        if (setsockopt(socket_desc,SOL_SOCKET,SO_REUSEADDR,&tr,sizeof(int)) == -1) {
            perror("setsockopt");
            exit(1);
        }
        
        if (socket_desc < 0){
            perror("ERROR opening socket");
            exit(1);
        }
    
        memset(&server, '0', sizeof (server));
        memset(client_message, '0', sizeof (client_message));
    
    
      
         
        //Prepare the sockaddr_in structure
        server.sin_family = AF_INET;
        server.sin_addr.s_addr = INADDR_ANY;
        server.sin_port = htons( 8888 );
         
        //Bind
        if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
        {
            //print the error message
            perror("bind failed. Error");
            return 1;
        }
        puts("bind done");
         
        //Listen
        listen(socket_desc , 3);
    
          long save_fd;
        
        save_fd = fcntl( socket_desc, F_GETFL );
        save_fd |= O_NONBLOCK;
        fcntl( socket_desc, F_SETFL, save_fd );
         
       
       
    } 
    
    tcp_schleife(){
    
            //Receive a message from client
                FD_ZERO(&fds);
                FD_SET(client_sock, &fds);
    
                select(1, &fds, NULL, NULL, NULL);
    
                if (FD_ISSET(client_sock, &fds))
                {
                    read_size = recv(client_sock , client_message , 10 , 0)
                    //add_client(&list, c);
                          //  while( (read_size = recv(client_sock , client_message , 10 , 0)) > 0 )
              //  {
                    //Send the message back to client
                    
                //    puts(client_message);
                   // char reply[10] = client_message;
                    write(client_sock , client_message , 10);
                    //test = 0;
    
                    for(int i = 0; i<11; i++){
                        printf("%d, ", client_message[i]);
                        
                    }
                    printf("\n");
                    printf("TEST2 %d\n",digitalRead(110));
    
                    switch (client_message[1]) {
                        case 1:
                            if(client_message[4] == 1) digitalWrite(100, LOW);
                            if(client_message[4] == 0) digitalWrite(100, HIGH);
                            digitalWrite(101, HIGH);
                            sleep(1);
                      //      printf("TEST2 %d\n",digitalRead(110));
                            while(!(digitalRead(110) == LOW)){
                               // printf("TEST");
                                
                            }digitalWrite(101, LOW);
                          // do something
                          break;
                        case 2:
                          // do something
                          break;
                        case 3:
                          // do something
                          break;
                        case 4:
                          // do something
                          break;
                        case 5:
                          // do something
                          break;
                        default:
                            break;
                          // do something
                    }
            //        return;
    
                    
               }
            
                 
                if(read_size == 0)
                {
                    puts("Client disconnected");
                    fflush(stdout);
                    close(socket_desc);
                    sleep(2);
                   // test = 1;
                }
                else if(read_size == -1)
                {
                    perror("recv failed");
                 //   test = 1;
                    close(socket_desc);
                }
    
    }
    
    int main(int argc , char *argv[])
    {   
        int test = 1;    
    
        
        configIO();
        configSocket();
        while(1){
                    checktimer();
    
                     //Accept and incoming connection
                   // puts("Waiting for incoming connections...");
                    c = sizeof(struct sockaddr_in);
         
                 //accept connection from an incoming client
                    client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
                    if (client_sock > 0)
                    {
                        puts("Connection accepted");
                        tcp_schleife();
                    }else{
                        usleep(5);
                    continue;
                    }
            
            }
    
    
    //    }
    
    }
    


  • Wenn ich mich recht erinnere blockiert recv() solang, bis Daten angekommen sind, die gelesen werden müssen. - Danach kommt er dann da auch wieder raus.



  • Richtig. Daher verwendet man vorher select oder pselect, um abzutesten, ob was auf dem Socket zum Empfang bereit ist.



  • Du wertest das Ergebnis von select nicht aus.

    Die 1 als erster Parameter ist falsch. Er muss client_sock + 1 sein.



  • select blockiert solange, bis einer der überwachten Kanäle Daten vorliegen hat.
    Aber es bietet über den letzten Parameter auch eine timeout-Funktion.

    Kennst du schon http://www.zotteljedi.de/socket-tipps/index.html ?



  • es muss doch was geben um den socket zu pollen ob er daten hat. dann kann man blocking vermeiden.



  • @rapper sagte in TCP Socket blockiert!:

    es muss doch was geben um den socket zu pollen ob er daten hat. dann kann man blocking vermeiden.

    http://beej.us/guide/bgnet/html/single/bgnet.html#blocking



  • Danke für den Link. Habe mir das auch soweit durchgelesen nur leider ist es wohl nicht ganz das was ich suche.
    Ich habe das jetzt auch weitestgehend angepasst. Das Problem nun... Wenn Der client sich connected in diesen 6 sek. (tv) dann ist er verbunden.
    Die funktion checktimer wird aber nicht aufgerufen...
    Erst wenn ich etwas schicke dann springt er in die Checktimer funktion, aber nur 1 mal. dann wartet der wieder.
    Nach 6 sek. springt der in else und bleibt in else bedinung hängen.

    Er soll aber eigentlich die Checktimer funktion parallel dazu aufrufen.

    FD_ZERO(&fds);
        FD_SET(socket_desc, &fds);
        while(1){
                    checktimer();
    
                     //Accept and incoming connection
                   // puts("Waiting for incoming connections...");
                    c = sizeof(struct sockaddr_in);
         
                 //accept connection from an incoming client
                select(socket_desc+1, &fds, NULL, NULL, &tv);
    
                if (FD_ISSET(socket_desc, &fds)){
                    client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
                    if (client_sock > 0)
                    {
                        puts("Connection accepted");
                        tcp_schleife();
                    }else{
                        usleep(5);
                        continue;
                    }
                }else{
                    printf("TEIMOUT\n");
                  //  continue;
                }
            
            }
    
    
    //    }


  • @mitch_m sagte in TCP Socket blockiert!:

    bleibt in else bedinung hängen

    Was soll das bedeuten?



  • Du wertest das Ergebnis von select immer noch nicht aus.



  • also falls dich das noch interessieren sollte: du kannst sockets auch als "nichtblockierend" erstellen und dann den rückgabewert auswerten (was du eh immer machen solltest). guckst du
    http://man7.org/linux/man-pages/man2/socket.2.html
    http://man7.org/linux/man-pages/man2/read.2.html


Log in to reply