2009-03-26 9 views
6

मैं सी में सॉकेट के माध्यम से कुछ फ़ाइल प्राप्त करने की कोशिश कर रहा हूं लेकिन सर्वर मुझे 1000000 बाइट फ़ाइल के लिए 64-बाइट पैकेट भेजता है उदाहरण के लिए और मुझे लगभग 999 9 0 बाइट मिलते हैं गंतव्य फ़ाइलसॉकेट के माध्यम से फ़ाइल स्थानांतरण, कम बाइट्स के साथ अंतिम आकार

while ((n = read(sd, buffer_in, BUFSIZE))) // BUFSIZE = 64 
{ 
    if(n<0) 
    { 
     printf("Fail.\n"); 
     fclose(archivo); 
     return -1; 
    } 

    if(fwrite(buffer_in, n, 1, f) !=1) 
    { 
     printf("fwrite error.\n"); 
     fclose(archivo); 
     return -1; 
    } 

    bytes+=n; 
} 

printf("We received %d bytes", bytes); 

जब एक स्थानीय टीसीपी/आईपी सॉकेट यह काम करता है के माध्यम से इस्तेमाल किया, लेकिन धीमे कनेक्शन में नहीं। मैं डिबगिंग के माध्यम से देखता हूं कि मुझे 64 बाइट भाग और ईओएफ के पास 30 बाइट खंड मिलते हैं। मुझे पता है कि जब आप किसी भी डेटा (> 1 बाइट) उपलब्ध होते हैं तो कॉल रिटर्न के बाद से आप कम बाइट प्राप्त कर सकते हैं। लेकिन इस स्थिति को थोड़ी देर तक पकड़ नहीं लिया जाना चाहिए? वापस लौटना चाहिए जब n == 0, यह कोई और डेटा (ईओएफ) नहीं है।

आपकी सहायता के लिए Thx।

(संपादित)

इस प्रकार कोड भेजा जा रहा है:

while (n=read(file_fd, buffer, BUFSIZE)) 
{ 
    write (sdaccept, buffer, n) 
} 

मुझे पता है कि दोनों पढ़ने() और लिखने() वापस आ सकते हैं एन < BUFSIZE, लेकिन नहीं उसके अनुसार इस पाश है कि बाहर काम करना चाहिए ? मैंने एन जोड़ा और 1000000, सटीक आकार देता है।

(संपादित द्वितीय)

10673 बाइट्स के साथ एक सी स्रोत के साथ परीक्षण किया गया, भ्रष्टाचार के बिना प्राप्त करता है 10575, सिवाय इसके कि गंतव्य फ़ाइल पहले 98 बाइट्स का अभाव है !!!

+0

लगभग 999,902? या बिल्कुल? – paxdiablo

+0

मुझे इस कोड में कोई स्पष्ट त्रुटियां नहीं दिखाई देती हैं - कृपया भेजने कोड भी दिखाएं। – Alnitak

+0

विशेष रूप से अजीब, क्योंकि 64 1000000 में विभाजित है –

उत्तर

11

प्रदान करने वाला कोड इस तथ्य को अनदेखा करता है कि एक सॉकेट पर लिखना() (या भेजना)) पूरे बफर को लिखने के लिए बाध्य नहीं है।

लिखना()/भेजना() लिखना()/भेजना() इसे आंशिक रूप से लिखने का फैसला कर सकता है या नहीं, अगर अंतर्निहित उपप्रणाली अधिक डेटा प्राप्त करने से इंकार कर देती है (उदाहरण के लिए नेटवर्क उपप्रणाली में डेटा भेजने के लिए कतार हो सकती है और यह कतार है पहले से ही पूर्ण)। धीमी कनेक्शन पर यह अत्यधिक संभावना है।

भेजने वाले पक्ष को यह जानने के लिए लिखने के लिए() के वापसी मूल्य की जांच करनी चाहिए कि वास्तव में कितना डेटा लिखा गया है और तदनुसार समायोजित किया गया है।

लिखें इस तरह किसी भी तरह से किया जाना चाहिए:

int readAmount; 
while(readAmount = read(file_fd, buffer, BUFSIZE) > 0) 
{ 
    int totalWritten = 0; 
    do { 
     int actualWritten; 
     actualWritten = write (sdaccept, buffer + totalWritten, readAmount - totalWritten); 
     if(actualWritten == - 1) { 
      //some error occured - quit; 
     } 
     totalWritten += actualWritten; 
    } while(totalWritten < readAmount); 
} 
+0

भेजना साइड कोड जोड़ा गया। –

+0

भेजना कोड वास्तव में वर्णित समस्या के लिए प्रवण है। सुझाए गए फिक्स जोड़ा गया। – sharptooth

+0

अभी भी 999 9 0 बाइट्स स्थानांतरित करता है !!!! :(:( –

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