C言語でソケットはどのように動作するのか?質問する

C言語でソケットはどのように動作するのか?質問する

C でのソケットプログラミングについては少し混乱しています。

ソケットを作成し、それをインターフェースとIPアドレスにバインドして、リッスンさせます。私はそれに関するいくつかのWebリソースを見つけ、よく理解しました。特に、私は記事を見つけました。 Unix システムでのネットワークプログラミング 非常に有益です。

私が混乱しているのは、ソケットにデータが到着するタイミングです。

パケットがいつ到着するか、パケットの大きさはどれくらいか、どうやって確認するのでしょうか。面倒な作業はすべて自分で行う必要があるのでしょうか。

ここでの私の基本的な仮定は、パケットは可変長である可能性があるということです。したがって、バイナリ データがソケットに表示され始めると、そこからどのようにパケットを構築し始めるのでしょうか。

ベストアンサー1

簡単に答えると、面倒な作業はすべて自分で行う必要があります。読み取り可能なデータがあることは通知されますが、何バイト読み取れるかはわかりません。可変長パケットを使用するほとんどの IP プロトコルでは、固定長がわかっているヘッダーがパケットの先頭に追加されます。このヘッダーにはパケットの長さが含まれます。ヘッダーを読み取り、パケットの長さを取得してから、パケットを読み取ります。通信が完了するまで、このパターン (ヘッダーを読み取り、パケットを読み取り) を繰り返します。

ソケットからデータを読み取るときは、特定のバイト数を要求します。読み取り呼び出しは、要求されたバイト数が読み取られるまでブロックされる可能性がありますが、要求されたバイト数よりも少ないバイト数が返される可能性があります。このような場合は、残りのバイトを要求して読み取りを再試行するだけです。

以下は、ソケットから一定数のバイトを読み取るための典型的な C 関数です。

/* buffer points to memory block that is bigger than the number of bytes to be read */
/* socket is open socket that is connected to a sender */
/* bytesToRead is the number of bytes expected from the sender */
/* bytesRead is a pointer to a integer variable that will hold the number of bytes */
/*           actually received from the sender. */
/* The function returns either the number of bytes read, */
/*                             0 if the socket was closed by the sender, and */
/*                            -1 if an error occurred while reading from the socket */
int readBytes(int socket, char *buffer, int bytesToRead, int *bytesRead)
{
    *bytesRead = 0;
    while(*bytesRead < bytesToRead)
    {
        int ret = read(socket, buffer + *bytesRead, bytesToRead - *bytesRead);
        if(ret <= 0)
        {
           /* either connection was closed or an error occurred */
           return ret;
        }
        else
        {
           *bytesRead += ret;
        }
    }
    return *bytesRead;
}

おすすめ記事