読者です 読者をやめる 読者になる 読者になる

recv

UNIXシステムコール Sample

recvは、アクセプトした相手から送られてきたバイトデータを読み込むUNIXシステムコール・・・。

Man page of RECV

アクセプトした相手のソケットファイルディスクリプタから、指定のバッファに、指定のサイズ分読み込む・・・。

今回は"end"が送られてくるまで、送られてくる文字列を出力するサーバを作る・・・。

バッファbuf、受信ループから抜けるフラグexit_flg、読み込んだ長さrecv_lenを用意・・・。

ソケット作成から、接続相手のIP表示まで・・・。

exit_flgが1になったら抜けるようなwhileループにする・・・。

recvでアクセプトした相手ソケットaccから、最大256バイト分読み込んでbufに格納する・・・。
実際に読み込まれた長さはrecv_lenに格納・・・。

末尾に改行"\r\n"が入ってしまってるので、除去する・・・。

strcmpでbufが"end"なら、exit_flgを1にしてこのループから抜ける・・・。
そうでなければ、printfでbufの内容を出力・・・。

ループから抜けたら、acc, socともにclose・・・。

$ ./recv
soc = 3
setsockopt(SO_REUSEADDR) success.
bind success.
listen success.

アクセプト待ちの状態になったら、telnetで3000ポートでアクセス・・・。

$ telnet bgstation0.com 3000
Trying 27.120.97.162...
Connected to bgstation0.com.
Escape character is '^]'.

一方、サーバは、

$ ./recv
soc = 3
setsockopt(SO_REUSEADDR) success.
bind success.
listen success.
accept!(IPAddress = 27.120.97.162, Port = 36234)

IPやポートを表示して読み込み待ちになっている・・・。
クライアント側から、文字列を入力する・・・。

$ telnet bgstation0.com 3000
Trying 27.120.97.162...
Connected to bgstation0.com.
Escape character is '^]'.
ABCDE

"ABCDE"を入力すると、

$ ./recv
soc = 3
setsockopt(SO_REUSEADDR) success.
bind success.
listen success.
accept!(IPAddress = 27.120.97.162, Port = 36234)
ABCDE

サーバに"ABCDE"が渡って、それを出力している・・・。
"XYZ"でも、

[bg1@dti-vps-srv93 recv]$ telnet bgstation0.com 3000
Trying 27.120.97.162...
Connected to bgstation0.com.
Escape character is '^]'.
ABCDE
XYZ

とすると、

$ ./recv
soc = 3
setsockopt(SO_REUSEADDR) success.
bind success.
listen success.
accept!(IPAddress = 27.120.97.162, Port = 36234)
ABCDE
XYZ

送られてるのがわかる・・・。
"end"で終了する・・・。

$ telnet bgstation0.com 3000
Trying 27.120.97.162...
Connected to bgstation0.com.
Escape character is '^]'.
ABCDE
XYZ
end
Connection closed by foreign host.
$

切断された・・・。
サーバ側は、

$ ./recv
soc = 3
setsockopt(SO_REUSEADDR) success.
bind success.
listen success.
accept!(IPAddress = 27.120.97.162, Port = 36234)
ABCDE
XYZ
$

こちらも終了している・・・。

Sample/recv.c at master · bg1bgst333/Sample · GitHub