2014-07-02 9 views
8

मेरे पास क्लाइंट-सर्वर एप्लिकेशन है।भेजने के लिए एकाधिक कॉल() को एक कॉल में विलय कर दिया जाता है()

क्लाइंट दो अलग send() कॉल का उपयोग करके एक पूर्णांक के बाद एक स्ट्रिंग भेज रहा है। इन दो डेटा को सर्वर पर दो अलग-अलग चरों में संग्रहीत किया जाना चाहिए।

समस्या यह है कि भेजे गए दोनों चर recv() कॉल पर प्राप्त किए जाते हैं। इसलिए, दो अलग send() एस द्वारा भेजे गए दो तारों को पहले recv() के बफर में संग्रहीत और संग्रहीत किया जाता है।

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

मैं इसे कैसे ठीक कर सकते हैं? मैं क्या गलत कर रहा हूं?

उत्तर

7

टीसीपी एक स्ट्रीमिंग प्रोटोकॉल है। यह किसी भी तरह की "संदेश" सीमाओं पर अवगत नहीं है। यह ऐसी जानकारी को send() पर एकल कॉल पर निर्भर नहीं करता है।

उन तथ्यों के कारण। प्रेषक पक्ष पर send() एस की किसी भी संख्या से रिसीवर पक्ष पर recv() एस (भेजे गए बाइट्स की संख्या तक) की संख्या हो सकती है।

इस व्यवहार को प्राप्त करने के लिए एक अलग-अलग "संदेश" को अलग करने के लिए एक अनुप्रयोग स्तर प्रोटोकॉल को परिभाषित और कार्यान्वित करने के लिए।

कोई recv()/send() पर भरोसा नहीं कर सकता है क्योंकि उन दो कार्यों को प्राप्त/भेजने के लिए कहा गया था। यह जानने के लिए कि उनके कार्यों को वास्तव में प्राप्त/भेजा गया है और उनके चारों ओर लूप कितना बाइट्स प्राप्त किया गया है, यह जानने के लिए उनके वापसी मूल्य की जांच करना एक आवश्यक आवश्यकता है जब तक प्राप्त/प्रेषित किए जाने वाले सभी डेटा प्राप्त/भेजे गए थे।

उदाहरण के लिए

कैसे इस "पाशन"

1

इस प्रकार टीसीपी काम करता है। इसे बाइट स्ट्रीम के रूप में देखें। इसके ऊपर कुछ बुनियादी प्रोटोकॉल रखें - कुछ ज्ञात बाइट मान के साथ आपको एप्लिकेशन संदेश डिलीमिट करें, या अपने संदेशों को लम्बाई फ़ील्ड के साथ प्रीपेड करें।

या यूडीपी पर स्विच करें, जो आपको डेटाग्राम सेमेन्टिक्स देता है, यदि आप कभी-कभी पैकेट नुकसान से सहन/पुनर्प्राप्त कर सकते हैं।

+0

" कुछ ज्ञात बाइट मान के साथ आपको एप्लिकेशन संदेश को सीमित करें "केवल स्पष्टीकरण के लिए, इसे प्रोटोकॉल कहा जाता है, कुछ लोग इस STXyourmessageETXXOR की तरह कुछ उपयोग करते हैं जहां हेक्स में एसटीएक्स (स्टार्ट) 2 है, हेक्स में ईटीएक्स (ईएनडी) 3 है, और एक्सओआर थोड़ा सा है ऑपरेशन^STXyourmessageE के लिए TX, परिणाम = STX^y -> परिणाम^= u ... जहां XOR सत्यापन के लिए अंक का प्रतिनिधित्व करता है –

संबंधित मुद्दे