WebHU - Programozási kérdések és válaszok

Különböző típusú üzenetek írása a C aljzatain keresztül

Üzenetet szeretnék küldeni a Binder osztályomnak a C nyelvű TCP socket kapcsolaton keresztül. Ezen a kapcsolaton át kell adnom egy kéréstípust (char*), ip címet (int), argTypes(int array) stb. ) módszerrel. Mi a legjobb módszer az összes információ egyetlen üzenetben történő elküldésére?

01.07.2012

  • Mivel próbálkoztál, és hogyan sikerült? 01.07.2012

Válaszok:


1

Nincs garancia arra, hogy egyetlen olvasási/írási művelettel el tudja küldeni/fogadni az összes adatot; túl sok tényező befolyásolhatja a minőséget/packet-size/connection-stability/etc.
Ez a kérdés/válasz ezt magyarázza meg.

Néhány C-példa itt.
Jó magyarázata a socket programozásáról C-ben.
A a TCP/IP gyors áttekintése.

A különböző típusú üzenetek küldése:
Az Ön által küldött adatokat a szerver-alkalmazásból kapja meg az ügyfélalkalmazás, amely aztán tetszés szerint értelmezheti ezeket az adatokat.

01.07.2012
  • Kérem a linkek tartalmát is beírni. Ez segítene a jövő olvasóinak abban az esetben, ha ezek a linkek kihalnak. 01.07.2012
  • @Thrustmaster: nem tudok róla: lehet, hogy jogvédett anyag azokon a linkeken? (Az internetes archívum segíthet – hogyan kezelik a jogvédett anyagokat?) Amúgy nem hiszem, hogy valaki más tartalmának meggondolatlan másolása jól jönne. 01.07.2012
  • Úgy értem, hogy a válasznak önmagában kell lennie; és nem kell a tartalom teljes húzásának lennie. Most nem tudok linkelni, de sok bejegyzés van róla a Metán. 01.07.2012
  • @Thrustmaster: ez a metahivatkozás: meta.stackexchange.com/a/113563/136755 és ez: meta.stackexchange.com/q/132911/136755 úgy tűnik, lefedi a problémát. 01.07.2012

  • 2

    Ha az adatok kapcsolódnak, létrehozhat egy struktúrát egy külön fejlécben, és használhatja mind a kliens, mind a kiszolgáló kódjában, és elküldheti ennek a struktúrának a változóját. Ha nem kapcsolódik egymáshoz, akkor nem tudom, miért kell egyetlen üzenetként elküldeni őket.

    01.07.2012

    3

    Ha egyetlen írással és egyszeri olvasással szeretné továbbítani és fogadni adatait, akkor datagram-foglalatot kell használnia. Mivel a datagram socket kapcsolat nélküli, nem használhatja a write/read. Ehelyett használja a sendto/recvfrom vagy sendmsg/recvmsg. Mivel a datagram socket megbízhatatlan, saját protokollt kell megvalósítania, hogy elviselje a renden kívüli adattovábbítást és adatvesztést.

    Ha nem akar foglalkozni a datagram socket megbízhatatlan természetével, akkor szeretne egy stream socketet. Mivel stream aljzat van csatlakoztatva, a továbbított adatok garantáltak és rendben vannak. Ha az elküldött adatok mindig azonos méretűek, akkor lemásolhat egy datagramot úgy, hogy blokkoló módot használ a send híváshoz, majd átadja a MSG_WAITALL recv hívást.

    #define MY_MSG_SIZE 9876
    
    int my_msg_send (int sock, const void *msg) {
        int r, sent = 0;
        do {
            r = send(sock, (const char *)msg + sent, MY_MSG_SIZE - sent,
                     MSG_NOSIGNAL);
            if (r <= 0) {
                if (r < 0 && errno == EINTR) continue;
                break;
            }
            sent += r;
        } while (sent < MY_MSG_SIZE);
        if (sent) return sent;
        return r;
    }
    
    int my_msg_recv (int sock, void *msg) {
        int r, rcvd = 0;
        do {
            r = recv(sock, (char *)msg + rcvd, MY_MSG_SIZE - rcvd, MSG_WAITALL);
            if (r <= 0) {
                if (r < 0 && errno == EINTR) continue;
                break;
            }
            rcvd += r;
        while (rcvd < MY_MSG_SIZE);
        if (rcvd) return rcvd;
        return r;
    }
    

    Figyelje meg, hogy a szoftvernek még mindig meg kell küzdenie bizonyos hibaesetekkel. EINTR esetén az I/O műveletet újra meg kell próbálni. Egyéb hibák esetén előfordulhat, hogy az adatok kézbesítése vagy visszakeresése nem teljes. Általában azonban a socketek blokkolásához csak egy iterációt várunk a fenti do-while hurokhoz.

    Ha üzenetei nem mindig azonos méretűek, akkor szüksége van egy módra az üzenetek keretezésére. A keretezett üzenet azt jelenti, hogy módra van szüksége az üzenet kezdetének és az üzenet végének észlelésére. Talán a legegyszerűbb módja annak, hogy egy üzenetet a streaming socket felett keretezzünk, ha az üzenet méretét megelőzzük. Ezután a vevő először a méretet olvassa fel, majd elolvassa az üzenet többi részét. Ehhez könnyen adaptálnia kell a my_msg_send és my_msg_recv mintakódját.

    Végül ott van magának az üzenetnek a kérdése. Ha az üzenetek nem mindig azonos méretűek, ez valószínűleg azt jelenti, hogy egy vagy több változó hosszúságú rekord van az üzenetben. Ilyen például egy értéktömb vagy egy karakterlánc. Ha a feladó és a fogadó is egyetért a rekordok sorrendjében, akkor elegendő minden változó hosszúságú rekordot megelőzni annak hosszával. Tehát tegyük fel, hogy az üzenet felépítése a következő:

    struct my_data {
        const char *name;
        int address;
        int *types;
        int number_of_types;
    };
    

    Ezután a struct my_data példányát így képviselheti:

    NAME_LEN : 4 bytes
    NAME : NAME_LEN bytes
    ADDRESS : 4 bytes
    TYPES_LEN : 4 bytes
    TYPES : TYPES_LEN * 4 bytes
    

    A NAME_LEN a strlen(msg->name)-ból, a TYPES_LEN pedig a msg->number_of_types-ből kapná az értékét. Amikor elküldi az üzenetet, azt a fenti üzenet teljes hossza előzi meg.

    32 bites mennyiségeket használtunk a hossz ábrázolására, ami valószínűleg elegendő az Ön céljaihoz. Ha egy számot aljzaton keresztül továbbítunk, a feladónak és a fogadónak meg kell állapodnia a szám bájtsorrendjében. Ez azt jelenti, hogy az 1-es szám 0.0.0.1 vagy 1.0.0.0. Ez általában a hálózati bájtrendezés segítségével kezelhető, amely az előbbit használja. A socket fejlécfájlok a htonl makrót tartalmazzák, amely a 32 bites értéket a gazdagép natív bájtsorrendjéből hálózati bájtsorrendgé alakítja. Ez akkor használatos, ha értéket tárol, például NAME_LEN. A vevő a megfelelő ntohl makróval visszaállítja az átvitt értéket a gazdagép által használt reprezentációra. A makrók természetesen nem lehetnek műveletek, ha a gazdagép natív bájtsorrendje már megegyezik a hálózati bájtsorrenddel. Ezeknek a makróknak a használata különösen fontos, ha heterogén környezetben küldünk és fogadunk adatokat, mivel a küldő és a fogadó eltérő állomás-byte-sorrenddel rendelkezhet.

    01.07.2012
    Új anyagok

    A rádiógomb ellenőrzött eseményének használata a jQueryben
    Ebben a cikkben látni fogjuk, hogyan kell dolgozni a jquery választógombbal ellenőrzött eseményeivel. A választógombok HTML gombok, amelyek segítenek kiválasztani egyetlen értéket egy csoportból...

    Körkörös függőségek megoldása terraformban adatforrásokkal – lépésről lépésre
    Mi az a körkörös függőségek Dolgozzunk egy egyszerű eseten, amikor az SQS-sor és az S3-vödör közötti körkörös függőség problémája van egy egymástól függő címkeérték miatt. provider..

    Miért érdemes elkezdeni a kódolást 2023-ban?
    01100011 01101111 01100100 01100101 — beep boop beep boop Világunk folyamatosan fejlődik a technológia körül, és naponta fejlesztenek új technológiákat a valós problémák megoldására. Amint..

    🎙 Random Noise #2  – Örökbefogadás és hit
    az analitika íratlan világának gondozása Szeretné, hogy ezek a frissítések a postaládájába kerüljenek? Iratkozzon fel itt . "Ha önvezető autókat gyártanak, akkor mi miért ne..

    A legrosszabb politika és prediktív modellek májátültetésre jelöltek számára az Egyesült Államokban
    A máj (vagy óangolul lifer) az emberi test legnehezebb belső szervére utal, amely csendesen működik a nap 24 órájában. Mit csinál a máj? 500 feladatot hajt végre a szervezet egészségének..

    5 webhely, amely 2022-ben fejleszti front-end fejlesztői készségeit
    Frontendmentor.io A tényleges projektek létrehozásával a Frontendmentor.io segítséget nyújt a front-end kódolási képességeinek fejlesztésében. A kódolást azután kezdheti meg, hogy..

    Mikor kell használni a Type-t az interfészhez képest a TypeScriptben?
    A TypeScript a JavaScript gépelt szuperkészlete, amely statikus gépelést ad a nyelvhez. Ez megkönnyíti a robusztus és karbantartható kód írását azáltal, hogy a hibákat a fordítási időben..