2016-04-12 4 views
0

Ich bin ein TCP-Handshake zwischen einem Client und einem Server zu entwickeln. In dem spezifischen der Client eine Nachricht an den Server senden, analysieren die Server die Nachricht und bieten eine Antwort. Das Problem ist, dass es scheint, dass, wenn der Server die Nachricht gibt es einige Probleme zurück zu senden hat, das heißt der Client und der Server blockiert werden.Sockel C Griff recv() und() zur gleichen Zeit senden

, dass mein Code Client-Seite ist:

if (connect(sock, (struct sockaddr *) &server_addr, sizeof(struct sockaddr)) 
     == -1) { 
    perror("Connect"); 
    exit(1); 
} 
char recv_data[2048]; 
first_message(user, mode, sock); 
    do { 
     bytes_recieved = recv(sock, recv_data, 1024, 0); 
     if (bytes_recieved == -1) { 
      printf("Error"); 
      exit(1); 
     } 
     printf("BYTE RECEIVED: %d\n", bytes_recieved); 
    } while (bytes_recieved != 0); 
    recv_data[bytes_recieved] = '\0'; 
    printf("%s", recv_data); 

Server-Seite:

sin_size = sizeof(struct sockaddr_in); 

    connected = accept(sock, (struct sockaddr *) &client_addr, &sin_size); 

    printf("\n I got a connection from (%s , %d)", 
      inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); 
    char recv_data[2048]; 
    do { 
     res = length_true - total; 
     bytes_recieved = recv(connected, recv_data + total, res, 0); 
     if (bytes_recieved == -1) { 
      printf("Recv() failed\n"); 
      break; 
     } 
     if (bytes_recieved > 0) { 
      total += bytes_recieved; 
     } 
    } while (bytes_recieved != 0); 
    int size_rcv = total; 
    recv_data[length_true - 1] = '\0'; 
    int b = 0; 
    printf("DATA RECEIVED:%s\n", recv_data); 
    send(connected,r,strlen(r),0); 
    fflush(stdout); 
    close (sock); 
    exit(1); 
    pause(); 
    return 0; 

Edit:

void common_frame(int sock, char *mode) { 

    const char *string_course = "DISTRIB2016"; 
    char *buf = (char*) malloc(22 * sizeof(char)); 
    char *buf_first = (char*) malloc(2 * sizeof(char)); 
    gethexes(buf_first, mode); //1 byte di modalità 
    gethexes(buf, string_course); //11 byte lunghezza del corso stringa 
    send(sock, buf, 22, 0); 
    send(sock, buf_first, 2, 0); 
    free(buf_first); 
    free(buf); 
} 

void first_command(int sock, char* user) { 
    char *frame = "T1"; 
    char *buf_second = (char*) malloc(4 * sizeof(char)); 
    char *username_length = (char*) malloc(sizeof(char)); 
    int user_len = strlen(user); 
    char *us = (char*) malloc(user_len *2 * (sizeof(char))); 
    gethexes(us, user); 
    gethexes(buf_second, frame); //2 byte of first command label T1 
    sprintf(username_length, "%d", user_len); 
    send(sock, buf_second, 4, 0); 
    send(sock, username_length, strlen(username_length), 0); //n byte username length 
    send(sock, us, strlen(us), 0); //username 
    free(username_length); 
    free(buf_second); 

} 

void first_message(char *user, char*mode, int sock) { 
    unsigned short int message_length; 
    char *length; 
    int user_len; 
    message_length = htons(17 + strlen(user)); 
    length = decimal_to_binary(message_length); //2 byte di lunghezza binaria in network order 
    send(sock, length, strlen(length), 0); 
    common_frame(sock, mode); 
    first_command(sock, user); 
} 

Mit dieser Implementierung Client und Server sind Stopp- und der Server kann keine Nachricht empfangen, aber wenn ich den Client magisch den Ser stoppen ver arbeitet und es empfängt und sendet die Daten korrekt.

+4

Mit dieser Implementierung und ohne zu sehen, was 'first_message()' tut, alles, was Sie möglicherweise ist voneinander ein Deadlock, während beide Seiten für die Eingabe warten, in Schleifen, die nicht beenden können, bis der Peer schließt die Verbindung bekommen. – EJP

+4

Sie wissen, dass Steckdosen sind standardmäßig * Sperrung *, und wenn es keine Daten ist dann zu lesen, die 'recv' Anrufe blockieren. Ohne zu wissen, was Ihre 'erste_Nachricht'-Funktion tut, scheint es so, als ob beide Programme einfach darauf warten, dass Daten empfangen werden. –

+4

Wenn Sie vor dem Lesen eines Sockets die Funktion 'select' verwenden, können Sie feststellen, ob etwas bereit ist, gelesen zu werden. – purplepsycho

Antwort

3

Wie in den Kommentaren erwähnt, tut Ihr Server nichts, bis recv() Null oder -1 zurückgibt, was bedeutet, dass der Client die Verbindung getrennt bzw. abgebrochen hat. Da Ihr Kunde keine dieser Dinge tut, haben Sie eine anwendungsbedingte Deadlock.

Verwandte Themen