العميل/الخادم: يتم استلام عدد صحيح دائمًا على أنه 1 (برمجة C)

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

  •  21-09-2019
  •  | 
  •  

سؤال

أقوم بإنشاء عميل وبرنامج خادم يتبادل البيانات عبر TCP وأواجه مشكلة في إرسال ACK-Conformation من الخادم إلى العميل عندما تكون العملية ناجحة. لقد تمكنت من إرسال بنية مع العديد من الأعضاء من العميل إلى الخادم ، ثم يجب على الخادم الاستجابة عن طريق إرسال عدد صحيح يؤكد معرف الهيكل إلى العميل.

في server.c لدي هذه الوظيفة:

int sendACK(int socket, int ack_int){

    int com_result;
    int ACK = htonl(ack_int);

    printf("\n\tSending ACK with value: %i", ack_int);

    com_result = send(socket, &ACK, sizeof(ACK), 0);

    if (com_result == -1) {
        perror("\n\t[ERROR] Send ACK");
        return 0;
    }

    return 1;

}

هذه الوظيفة تسمى وظيفة أخرى في server.c مثل هذا:

int ACK = myStruct->ID;
sendACK(socket, ACK);

لذا ، إذا كنت قد تلقيت للتو هيكلًا يحتوي على معرف: 2 ، فسيكون الإخراج:
إرسال ACK مع القيمة: 2

في Client.c أتلقى ACK مثل هذا:

int ACK = 0;
data_size  = sizeof(myStruct.ID);
com_result = read(client_socket, &ACK, data_size);
ACK = ntohl(ACK);

if (com_result == -1) {
    perror("\n\t[ERROR] Read");
} else {
    printf("\n\tRecieved %i of %i bytes", com_result, data_size);
    if (ACK != myStruct.ID) {
        printf("\n\t[ERROR] Invalid ACK (%i).", ACK);
    }
}

ولكن يتم استلام ACK دائمًا بقيمة 1 ، وبالتالي فإن الإخراج من العميل هو:
تم استلام 4 من 4 بايت
خطأ] ACK غير صالح (1).

لماذا لا يتم استلام عدد صحيح بقيمة 2, ، وكيف يمكنني إصلاح هذا؟

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

المحلول

على الأرجح ليست المشكلة ، لكنني أعتقد أن الخط الثاني في SPANE.C SNIPPET أدناه يجب أن يكون SizeOF (ACK).

int ACK = 0;
data_size  = sizeof(ACK); // was: sizeof(myStruct.ID);
com_result = read(client_socket, &ACK, data_size);
ACK = ntohl(ACK);

أيضًا ، بناءً على تدفق البيانات الخاص بك ، هل من الممكن أن تقرأ بالفعل بشكل صحيح وأن ACK هو الاستجابة من حزمة أرسلتها مسبقًا؟

نصائح أخرى

يجب ألا ترسل قيمًا كاملة مثل هذا ، فأنت بحاجة إلى إيلاء المزيد من الاهتمام للتسلسل. قد يفشل هذا إذا ، على سبيل المثال ، sizeof (int) يختلف على جهاز الإرسال من جهاز الاستقبال ، وفي هذه الحالة ستقرأ العدد غير الصحيح من البايتات.

من الأفضل أن تعني المزيد من الحقول وتسلسلها بايت واحد في وقت واحد.

من أجل تصحيحه ، يمكنك استخدامه Wireshark. ينفذ Wireshark وتعيين خياراته للاستماع إلى المنفذ المطلوب. سترى ما تم إرساله بالفعل داخل الحزمة عبر الشبكة. سيسمح لك ذلك بفهم ما إذا كانت المشكلة مع الخادم أو العميل أو كليهما.

لا يمكنني معرفة أي شيء خاطئ في الكود الذي لصقه أعلاه. أود أن أقترح الخروج من برنامج Wireshark ، أو برنامج تتبع المقبس الآخر ، والنظر إلى البتات الموجودة على السلك.

أتحقق من أن رمز المرسل/المتلقي الرئيسي الخاص بك هو التعامل مع الكمية الصحيحة من البيانات.

إذا أرسل المرسل الخاص بك 20 بايت متبوعًا بأربعة بايت ACK ، لكن المتلقي يقرأ 16 فقط قبل محاولة قراءة ACK ، فقد يواجه هذا النوع من المشكلات.

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top