1

を使用して、「データサイズ」と「データ」の両方を特定のファイル記述子に送信するために課金される関数を使用したいと思いますwrite()。レコード長が 2 バイトの場合に機能します。ただし、同じ関数を使用して、1 バイトに等しいレコード長も送信したいと考えています。

send_func(int port)
{
    void *fd;
    uint64_t fsize = 2517283;
    uint64_t nbrBytes = 0;  
    uint16_t rsize;
    int count;
    ssize_t ret;
    uint8_t Bsent = 0;

    for (count = 1; nbrBytes < fsize; count++) 
    {
        rsize = ((uint8_t*)fp)[nbrBytes];
        rsize += ((((uint8_t*)fp)[nbrBytes + 1]) << 8) & 0xFF00;
        nbrBytes += 2;

        // send size
        ret = write(port, rsize, 2);
        if (ret != 2) {
            return -1;
        }
        // send data
        ret = write(port, ((unsigned char*)fp) + Bsent, rsize - Bsent);
        if (ret < 0) {
            return -1;
        }
        Bsent += ret;
    }
}

send_func(int port)
{
    void *fd;
    uint64_t fsize = 2517283;
    uint64_t nbrBytes = 0;  
    size_t rsize;
    int count;
    ssize_t ret;
    uint8_t Bsent = 0;

    for (count = 1; nbrBytes < fsize; count++) 
    {
        if (mode == ONLY_1_BYTE) {
            rsize = ((uint8_t*)fp)[nbrBytes];
            rsize += ((((uint8_t*)fp)[nbrBytes + 1])); 
            nbrBytes += 1;

            do {
                // send data
                ret = write(port, ((unsigned char*)fp) + Bsent, rsize - Bsent);
                if (ret < 0) {
                    return -1;
                }  
                Bsent += ret;
            } while(Bsent < rsize)     
        }
        else
        {
            rsize = ((uint8_t*)fp)[nbrBytes];
            rsize += ((((uint8_t*)fp)[nbrBytes + 1]) << 8) & 0xFF00;
            nbrBytes += 2;   

            // send size
            ret = write(port, rsize, sizeof(uint16_t));
            if (ret != 2) {
                return -1;
            }        
        }

        do {
            // send data
            ret = write(port, ((unsigned char*)fp) + Bsent, rsize - Bsent);
            if (ret < 0) {
                return -1;
            }  
            Bsent += ret;
        } while(Bsent < rsize)
    }
}

2 番目のケースでは長さが 1 バイトしかないため、2 バイトの場合に必須であるエンディアン操作を自発的に削除しました。

それは練習するための最良の方法ですか?

4

1 に答える 1

1

投稿したコードを改善するために適用できるいくつかのベスト プラクティス:

  • ストリームから 1 バイトを最適化することについて心配する必要はありません。それは問題ではありません。ペイロードとは別に、イーサネット フレームごとに約 60 バイトのオーバーヘッドがかかることをご存知ですか?
  • エンディアン スワップをハンドロールしないでください。などの組み込み関数を使用しますhtons()
  • からの戻り値write()が送信しようとした値よりも小さい「短い書き込み」を考慮する必要があります。その場合write()、長さのプレフィックスを再送信せずに、ループして再度呼び出す必要があります。
于 2015-12-15T16:05:36.833 に答える