نقل الملفات من خلال مآخذ، الحجم النهائي مع أقل بايت

StackOverflow https://stackoverflow.com/questions/684733

  •  22-08-2019
  •  | 
  •  

سؤال

وأنا أحاول الحصول على بعض الملفات من خلال مآخذ في C. ولكن الخادم يرسل لي الحزم 64 بايت للملف 1000000 بايت على سبيل المثال وأحصل على ما يقرب من 999902 بايت على الملف الوجهة.

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

عند استخدامها من خلال مأخذ TCP / IP المحلي يعمل، ولكن ليس في اتصال بطيء. أرى من خلال التصحيح أن أحصل على الكثير من قطع 64 بايت، وقطعة 30 بايت بالقرب EOF. وأنا أعلم أنه يمكنك الحصول على أقل بايت على قراءة () منذ إرجاع الاستدعاء عند أي بيانات (> 1 بايت) متاحة. ولكن هذا الشرط لا ينبغي أن catched من الوقت؟ يجب أن تعود عندما ن == 0، وهذا هو عدم وجود بيانات المزيد (EOF).

وتشك لمساعدتكم.

و(تحرير)

وإرسال التعليمات البرمجية كما يلي:

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

وأنا أعلم أن كلا قراءة () والكتابة () قد ترجع N

و(تحرير II)

واختبارها مع مصدر C مع 10673 بايت، يتلقى 10575 بدون فساد، إلا أن الملف الوجهة يفتقر إلى بايت 98 الأولى!

هل كانت مفيدة؟

المحلول

والرمز إرسال المقدمة يتجاهل حقيقة أن الكتابة () (أو إرسال ()) على مأخذ توصيل ليست مضطرة لكتابة المخزن المؤقت كله.

والكتابة () / إرسال () قد قررت أن تكتب بشكل جزئي أو عدم كتابة على الإطلاق إذا رفض النظام الفرعي الأساسي لتلقي مزيد من البيانات (على سبيل المثال قد يكون النظام الفرعي شبكة طابور للبيانات لإرسال وهذا الطابور هو بالفعل ممتلئ). أن من المرجح بدرجة كبيرة على اتصال بطيء.

والجانب ارسال يجب أن تحقق قيمة الإرجاع من الكتابة () للكشف عن كمية البيانات قد كتب فعلا وضبط وفقا لذلك.

وينبغي أن يتم ذلك بطريقة أو بأخرى كتابة مثل هذا:

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 );
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top