2014-07-02 20 views
8

Tôi có một ứng dụng client-server.Nhiều cuộc gọi để gửi() được hợp nhất thành một cuộc gọi đến recv()

Máy khách đang gửi một chuỗi theo sau là số nguyên sử dụng hai cuộc gọi send() riêng biệt. Hai dữ liệu này được cho là được lưu trữ thành hai biến khác nhau trên máy chủ.

Vấn đề là cả hai biến được gửi đều được nhận vào cuộc gọi recv(). Do đó, hai chuỗi được gửi bởi hai khác biệt send() s được ghép và lưu trữ trong bộ đệm của recv() đầu tiên.

server.c:

printf("Incoming connection from client %s:%i accepted\n",inet_ntoa(clientSocketAddress.sin_addr),ntohs(clientSocketAddress.sin_port)); 


memset(buffer,0,sizeof(buffer)); 
int sizeofMessage; 
if ((recv(clientSocket,buffer,MAXBUFFERSIZE,0)==sizeofMessage)<0) 
{ 
    printf("recv failed."); 
    closesocket(serverSocket); 
    clearWinsock(); 
    return EXIT_FAILURE; 
} 

char* Name=buffer; 
printf("Name: %s\n",Name); 

if ((recv(clientSocket,buffer,MAXBUFFERSIZE,0))<0) 
{ 
    printf("bind failed."); 

    closesocket(serverSocket); 
    clearWinsock(); 
    return EXIT_FAILURE; 
} 

int integer=ntohs(atoi(buffer)); 
printf("integer: %i\n",intero); 

client.c:

if (send(clientSocket,Name,strlen(Name),0)!=strlen(Name)) 
{ 
    printf("send failed"); 

    closesocket(clientSocket); 
    clearWinsock(); 
    return EXIT_FAILURE; 
} 

printf("client send: %s",Name); 

int age=35; 
itoa(htons(age),buffer,10); 
sizeofBuffer=strlen(buffer); 
if (send(clientSocket,buffer,sizeofBuffer,0)!=sizeofBuffer) 
{ 
    printf("bind failed."); 

    closesocket(clientSocket); 
    clearWinsock(); 
    return EXIT_FAILURE; 
} 

Làm thế nào tôi có thể sửa chữa nó? Tôi đang làm gì sai?

Trả lời

7

TCP là giao thức truyền trực tuyến. Nó không phải là nhận thức ở tất cả các loại "tin nhắn" ranh giới. Nó không thêm thông tin như vậy phụ thuộc vào các cuộc gọi đơn lẻ đến send().

Do những sự kiện đó. Bất kỳ số lượng send() s ở phía người gửi có thể dẫn đến bất kỳ số lượng recv() s (tối đa số byte được gửi) ở phía người nhận.

Để khắc phục hành vi này, hãy xác định và triển khai giao thức mức ứng dụng để phân biệt các "thông báo" khác nhau đã được gửi.

Không thể dựa vào số recv()/send() nhận/gửi nhiều byte khi hai chức năng đó được yêu cầu nhận/gửi. Đó là một điều cần thiết cần thiết để kiểm tra giá trị trả về của họ để tìm hiểu số byte thực sự nhận được/gửi và lặp lại chúng cho đến khi tất cả dữ liệu được nhận/gửi đã được nhận/gửi.

Đối với ví dụ cách này "Looping" có thể được thực hiện

1

Đây là cách TCP hoạt động. Coi nó như một dòng byte. Đặt một số giao thức cơ bản lên trên nó - phân định các thông báo ứng dụng của bạn với một số giá trị byte đã biết hoặc thêm thông điệp của bạn với trường độ dài.

Hoặc chuyển sang UDP, cung cấp cho bạn ngữ nghĩa datagram mà bạn đang tìm kiếm, nếu bạn có thể chịu đựng/phục hồi sau khi mất gói dữ liệu thường xuyên.

+0

" delimit bạn thông điệp ứng dụng với một số giá trị byte đã biết "chỉ để làm rõ, điều này được gọi là giao thức, một số người sử dụng một cái gì đó như thế này STXyourmessageETXXOR nơi STX (bắt đầu) trong HEX là 2, ETX (END) trong HEX là 3, và XOR là một bitwise hoạt động^cho STXyourmessageE TX, kết quả = STX^y -> kết quả^= u ... trong đó XOR biểu diễn chữ số để xác minh –

Các vấn đề liên quan