質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

TCP

TCP(Transmission Control Protocol)とは、トランスポート層のプロトコルで、コネクション型のデータサービスです。

Q&A

解決済

1回答

3590閲覧

C言語TCPクライントでfinパケットを受信したい

tedmosby

総合スコア46

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

TCP

TCP(Transmission Control Protocol)とは、トランスポート層のプロトコルで、コネクション型のデータサービスです。

0グッド

0クリップ

投稿2020/07/14 02:50

現在C言語でソケットプログラミングを学んでいて、selectコールを利用したTCPサーバーとTCPクライントを実装しています。
サーバプロセスが終了するとき、FINパケットをクライアントに送信して、「Server is down.」等のメッセージを表示 して終了するようにクライアントを改良したいのですが、どのようにすればよいのでしょうか??
recv()でFINパケットを受け取ればよいのでしょうか??

ちなみにクライント側のプログラムは以下のようになっています

c

1void tcp_client(char* servername, int port_number) 2{ 3 int sock; 4 char s_buf[S_BUFSIZE], r_buf[R_BUFSIZE]; 5 int strsize; 6 fd_set mask, readfds; 7 8 /* サーバに接続する */ 9 // 自作ライブラリの関数 10 sock = init_tcpclient(servername, port_number); 11 printf("Connected.\n"); 12 13 /* ビットマスクの準備 */ 14 // fd_set型変数maskの初期化 15 FD_ZERO(&mask); 16 // maskの第0番目とsock番目を1にする、ビットが1であれば監視をするという意味 17 FD_SET(0, &mask); 18 FD_SET(sock, &mask); 19 // 標準入力(0番目)と サーバとの接続用に開いたソケット(sock番目)を監視する 20 21 for(;;){ 22 23 /* 受信データの有無をチェック */ 24 // サーバからの入力があるかをselect()で確認する 25 readfds = mask; 26 select(sock+1, &readfds, NULL, NULL, NULL); 27 28 if( FD_ISSET(0, &readfds) ){ 29 // FD_ISSET(0, &readfds)が真であればキーボードから入力があったとわかる→送信 30 31 /* キーボードから文字列を入力する */ 32 fgets(s_buf, S_BUFSIZE, stdin); 33 strsize = strlen(s_buf); 34 Send(sock, s_buf, strsize, 0); 35 // sendにエラー処理を加えた自作関数 36 } 37 38 if( FD_ISSET(sock, &readfds) ){ 39 // FD_ISSET(sock, &readgds)でサーバからパケットが届いているか確認できる→受信 40 41 /* サーバから文字列を受信する */ 42 strsize = Recv(sock, r_buf, R_BUFSIZE-1, 0); 43 r_buf[strsize] = '\0'; 44 printf("%s",r_buf); 45 fflush(stdout); /* バッファの内容を強制的に出力 */ 46 } 47 48 } 49 50}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dodox86

2020/07/14 04:43

一般的にソケットのプログラミングでFINなどのTCPフラグを直接扱うことはしません。FINは、closeシステムコールでコネクションを切断すると自動的に相手側に送信されます。相手側はrecvシステムコールで受信待ちしていたとき、受信長0バイトで返ります。一般的にTCPクライアントサーバープログラミングでは、recvで0が返ってきたら切断されたと判断します。selectで待っていた場合、recvのfdがセットされるはずです。それでも尚、FINを含むフラグを直接扱いたいのであれば、RAWソケットで生のパケット操作を行えばできるでしょうが、恐らくすごく大変です。ご質問はそれを踏まえて尚、FINを直接送りたい、と言う内容なのでしょうか。
guest

回答1

0

自己解決

recv()で0を受け取ったら終了するように修正した。

投稿2020/07/14 14:32

tedmosby

総合スコア46

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問