kumitatepazuru's blog

中学生のメモブログ。みんなの役に立ちたい。

soccerAIのプログラムレベルのお話(α0.4) ①

f:id:kumitatepazuru:20200624184450p:plain

6/25現在未公開のα0.4でPORTの変更をして手動だが、サッカーを沢山実行できるようになったが、面倒くさいので自動化する。 その時に自動でPORTを設定する方法に手こずったのでメモ。 PORTのお話はこちら。

kumitatepazuru.hatenablog.com

どーしたの?

前までは以下の手法を使ってポートを設定していた。

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で処理しているのはまずい。

どーやった?

調べてみると、こんな記事が。

stackoverflow.com

抜粋すると

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 シミュレーションリーグのチームでは参加者募集中です!活動の見学、活動に参加したい方、ご連絡お待ちしております!

詳しくはこちら

kumitatepazuru.github.io

*1:'', 0