İ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.
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
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. –
Bir sokette okumadan önce 'select' işlevini kullanmak, okunacak bir şey olup olmadığını size söyleyecektir. – purplepsycho