2016-04-12 13 views
0

İstemciyle sunucu arasında TCP el sıkışması geliştiriyorum. İstemciye sunucuya bir mesaj gönderin, sunucu mesajı analiz eder ve bir cevap verir. Sorun, sunucunun mesajı geri göndermesi gerektiğinde bazı problemler olduğu, yani istemci ve sunucunun engellendiği anlaşılıyor. Benim kod İstemci tarafıSoket C recv() 'yi kullanın ve aynı anda gönderin()

:

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); 

Sunucu tarafı:

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; 

Düzenleme: Bu uygulama istemci ve sunucu hem Tam

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); 
} 

durdurma ve sunucu olan herhangi bir mesaj alamaz ancak istemciyi sihirli bir şekilde durdurursam Ver çalışır ve verileri doğru bir şekilde alır ve gönderir.

+4

Bu uygulama ile ne 'first_message()' ın ne yaptığını görmeden, her iki tarafın da birbirlerinin girişini beklerken, eşler bağlantıyı kapatana kadar sona erdirilemeyen döngülerdeki olası bir kilitlenme olur. – EJP

+4

Soketler varsayılan olarak * engelleme * olduğunu biliyorsunuz ve okunacak veri yoksa, 'recv' çağrıları engelleyecektir. 'First_message' işlevinin ne yaptığını bilmeden, her iki programın da alınması gereken verileri beklemesi gibi görünüyor. –

+4

Bir sokette okumadan önce 'select' işlevini kullanmak, okunacak bir şey olup olmadığını size söyleyecektir. – purplepsycho

cevap

3

Açıklamalarda belirtildiği gibi, sunucunuz sıfır veya -1 değerini döndürene kadar hiçbir şey yapmaz, yani istemcinin bağlantısı kesilir veya bağlantıyı kesmesi anlamına gelir. Müşteriniz bu şeylerden hiçbirini yapmadığı için, uygulamanın neden olduğu bir çıkmaza sahip olursunuz.