Armadilloフォーラム

Armadillo-460のTCPソケット通信時のポートの再利用について

kunimaru

2021年10月8日 16時18分

お世話になります。

Armadillo-460を使用してTCPソケット通信のサーバーを作成しているものです。

TCPソケット通信時のポートの再利用について質問です。

以下コードでソケットを開いてクライアントとの通信後に
サーバー側でいったんソケットをcloseし、
同じポートを再度開こうとしても、しばらく間bindがエラーになります。
これはTCP規格でcolse後の一定時間の終了待機状態になることが原因であることは調べることができました。

	sock0 = socket(AF_INET, SOCK_STREAM, 0);
 
	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);
	addr.sin_addr.s_addr = INADDR_ANY;
 
	if (bind(sock0, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
		printf("[ERROR] bind error. \n");
		return;
	}
	if (listen(sock0, 5) != 0) {
		printf("[ERROR] listen error. \n");
		return;
	}

また、以下のようにSO_REUSEADDRの設定を追加すれば、エラーにならないことも確認できました。

	sock0 = socket(AF_INET, SOCK_STREAM, 0);
 
	// 追加部分
	on = 1;
	setsockopt( sock0, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) );
	//   
 
	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);
	addr.sin_addr.s_addr = INADDR_ANY;
 
	if (bind(sock0, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
		printf("[ERROR] bind error. \n");
		return;
	}
	if (listen(sock0, 5) != 0) {
		printf("[ERROR] listen error. \n");
		return;
	}

ただ、この場合一時的に同じポートに複数の接続が存在することになります。
できれば複数存在する状態を避けたいので、
SO_REUSEADDRの設定する以外の方法を模索しています。

終了待機状態にならないようにcloseする、
終了待機状態の接続を強制的に終了させる等
単一の接続でポートをすぐに再利用できる方法をご存知でしたら、
ご教授いただけないでしょうか?

よろしくお願いいたします。

以上

コメント

at_shinya.koga

2021年10月8日 17時21分

アットマークテクノの古賀です。

kunimaruさん:
>Armadillo-460を使用してTCPソケット通信のサーバーを作成しているものです。
>
>TCPソケット通信時のポートの再利用について質問です。
>
>以下コードでソケットを開いてクライアントとの通信後に
>サーバー側でいったんソケットをcloseし、
>同じポートを再度開こうとしても、しばらく間bindがエラーになります。
>これはTCP規格でcolse後の一定時間の終了待機状態になることが原因であることは調べることができました。

>ただ、この場合一時的に同じポートに複数の接続が存在することになります。
>できれば複数存在する状態を避けたいので、
>SO_REUSEADDRの設定する以外の方法を模索しています。
>
>終了待機状態にならないようにcloseする、
>終了待機状態の接続を強制的に終了させる等
>単一の接続でポートをすぐに再利用できる方法をご存知でしたら、
>ご教授いただけないでしょうか?

graceful close(正当な切断)処理を行う、というのが解だと思います。具体的には、close() して終わりではなく、shutdown() -> read() -> close() という手順でソケットをクローズするようにしてみて下さい。graceful close/graceful shutdown については、たとえば、以下のページが参考になるかと思います:

・Graceful Shutdown Server Socket in Linux
 https://stackoverflow.com/a/9682704

・TCP/IP ソケットプログラミング C 言語編
 https://books.google.co.jp/books?id=GRWmc5Z_SdIC&pg=PA138&lpg=PA138&dq=…

・Graceful Shutdown, Linger Options, and Socket Closure (※Windows のドキュメントです)
 https://docs.microsoft.com/en-us/windows/win32/winsock/graceful-shutdow…

kunimaru

2021年10月8日 23時44分

古賀 様

kunimaruです。

早急にご回答および参考サイトをご紹介いただき、ありがとうございます。
月曜日になってしまいますが、ご教授いただいた方法を試してみます。

以上