soccerAIのプログラムレベルのお話(α0.4) ①
6/25現在未公開のα0.4でPORTの変更をして手動だが、サッカーを沢山実行できるようになったが、面倒くさいので自動化する。 その時に自動でPORTを設定する方法に手こずったのでメモ。 PORTのお話はこちら。
どーしたの?
前までは以下の手法を使ってポートを設定していた。
self.s = socket(AF_INET, SOCK_DGRAM) ok = 0 i = 0 print("\033[38;5;12m[INFO]\t\033[38;5;13mSearching for available ports ...\033[0m") while ok == 0: try: self.s.bind((HOST, 1000 + i)) ok = 1 except OSError: i += 1 self.recieve_port = 1000 + i
でも、これじゃあ読み込みに時間がかかるし、何より、exceptで処理しているのはまずい。
どーやった?
調べてみると、こんな記事が。
抜粋すると
Do not bind to a specific port, or bind to port 0, e.g. sock.bind*1. The OS will then pick an available port for you. You can get the port that was chosen using sock.getsockname()[1], and pass it on to the slaves so that they can connect back.
日本語に直して要約すると
特定のポートにアクセスして確認する方法等はやめたほうがいいぜ
bindのポートの部分に0を入れるとOSがポートを適当に選んでくれるぜ
sock.getsockname()[1]を実行すると、OSが選んだポートがわかるぜ(=このポートは空いている)
ということ。 だから、こんなプログラムにした。
s = socket(AF_INET, SOCK_DGRAM) s.bind((args.host, 0)) p1 = s.getsockname()[1] s.close()
こうすると、p1に適切なポートが入る。そして、bindしたポートはs.close()
でポートを閉じているので使用が可能になっている。
サッカーサーバーは3つのサーバーポートを使用するので3回同じことを繰り返す。そうすると、使っていないポート3つが取得できる。
最後に
このシステムを調べるのに30分くらいかかった。また、次のバージョンのtensorboardも同じ機能を使っている。
個人的な質問等はこちらまで。
https://forms.gle/V6NRhoTooFw15hJdA
また、自分が参加しているRobocup soccer シミュレーションリーグのチームでは参加者募集中です!活動の見学、活動に参加したい方、ご連絡お待ちしております!
詳しくはこちら
*1:'', 0