readとfread,recvの違い
C言語で簡易HTTPサーバを作成する際に、ブラウザに返すファイルを読み込むのに何を使おうと迷ったため、調べることにしました。
【違い】
readとrecv
read は recv の flags パラメータ(第4引数)に0を与えたものと同一。flagsパラメータに他の値を与えるとrecvの振る舞いが変わる。同様に、writeはflags==0のときのsend と同一。
readとfread
- read:低水準入出力関数
- fread:高水準入出力関数/ストリーム関数
高水準入力関数は、対象ファイルを読み込んだ後それを一度OSが管理するメモリ上に置き、指定メモリ領域にコピーをする。
一方で低水準入出力関数では、ソースから指定メモリ領域にコピーされる。そのため、あるファイルを一度だけ読み書きする場合には低水準入出力関数の方が高速にアクセスが可能となる。
参考ページ:プログラマー向けブログ
各関数の使い方は以下。
【read】
ファイルからのデータの読み込みを行う低水準入出力関数。
使い方
int read(
int handle, //ファイルハンドル
void *buf, //データ格納先アドレス
int length //bufパラメータの指すバッファーのバイト単位長
)
戻り値
完全に成功すると、受信データのバイト数
ソケットがクローズされると、0
読み取り途中で失敗すると、読み取りに成功した部分のバイト数
まだデータを読み取っていないと、-1
詳細は以下を見よう。
参考ページ:IBM Knowledge Center - read
【fread】
ブロック単位でデータを読み込む高水準入出力関数。
ファイル構造体を介してファイルにアクセスする。
使い方
size_t fread(
void *buff, //データ格納先アドレス
size_t size, //読み込むデータ1つのバイト数
size_t n, //読み込むデータの個数
FILE *fp //ファイルポインタ
)
戻り値
完全に成功すると、受信データのブロック数(size)
何かしら失敗すると、sizeより小さい値
詳細は以下を見よう。
参考ページ:C言語入門/関数リファレンス
【recv】
接続されたソケットまたはバインドされた非接続ソケットからデータを受信する関数。
使い方
int recv(
int socket, //socketディスクリプタ
char *buf, //データ格納先アドレス
int length, //データ長
int flags //flgas
)
- socket 接続されたソケットを識別する記述子
- buf データを受け取るバッファーへのポインタ
- length bufferがさすバイト単位の長さ
- flags 呼び出しをどのように行うかを指定するフラグ
戻り値
成功すると、受信データのバイト数
ソケットがクローズされると、0
失敗すると、-1を戻す
詳細は以下を見よう。
参考ページ:ちょくとのページ - recv