こんにちは!
前回はPowershellを使ったTCPクライアントの作り方について解説しました。今回はクライアントに続きTCPListenerの作り方を解説していきたいと思います。今回使用する言語はPowershellですが、基本的な流れはC#やPythonなど他の言語にも応用できるのでこれを機にネットワークプログラミングの基礎を抑えておきましょう。
↓前回の記事はこちらから
実行環境
・OS:Windows10 開発環境:Powershell ISE
TCPListenerのソースコード
TCPListenerのソースコードは以下の通りです。先頭の数字は前回と同様解説をわかりやすくするために記載していますので、もし実際にソースコードを参考にする場合はサクラエディタなどで数字を削除してください。書き方についてはTCPクライアントと似ている部分もあるので前回の内容が理解できていればある程度流れが想像できるかと思います。今回はTCPListenerクラスを用いて接続要求の受付を行い、接続を確立した後はリスナー側でコンソールから入力した文字列をクライアント側に送信します。
1 try {
2 $IPAddress = New-Object System.Net.IPAddress(0x030ba8c0)
3 $listener = New-Object System.Net.Sockets.TcpListener($IPAddress, 7777)
4 $buffer = New-Object System.Byte[] 1024
5 $encoding = New-Object System.Text.AsciiEncoding
6 $listener.Start()
7
8 $data = ""
9 $socket = $listener.AcceptSocket()
10 $stream = New-Object System.Net.Sockets.NetworkStream($socket)
11 $writer = New-Object System.IO.StreamWriter($stream)
12
13 Write-Host "Established!"
14
15 while($true) {
16 start-sleep -m 100
17 while($stream.DataAvailable){
18 $read = $stream.Read($buffer, 0, 1024)
19 $data = $encoding.GetString($buffer, 0, $read)
20 }
21 Write-Host $data
22 $message = Read-Host "Input a message "
23
24 if ($message) {
25 $writer.write($message)
26 $writer.flush()
27 $data = ""
28 }
29 }
30 } finally {
31 $socket.Dispose()
32 $listener.stop()
33 }
接続の要求受付を行いセッションを確立する
2行目~3行目:3行目でTCPListenerクラスを生成する際、引数にIPAddressクラスを渡す必要があるので1行目でIPAddressクラスのオブジェクトを生成して$IPAddressに代入しています。IPAddressクラスを生成している時の引数が0x030ba8c0となっていますが、これは16進数形式でIPAddressを指定する必要があるためです。16進数表記で03が3、0bが11、a8が168、c0が192で3.11.168.192を表しており、順番を逆にすると192.168.11.3で今回接続を受け付けるIPAddressになっています。
4行目~5行目:ネットワークから読みだしてきたデータの値を代入するため、1024個の要素を持つByte型の配列を用意します。またネットワークから読みだされる値は文字コードに変換された値になっているので、人間に読める値に変換するためのメソッドを持つAscii.Text.Encodingクラスを生成します。
6行目~11行目:6行目の$listener.Start()で接続の受付を開始したうえで、9行目の$socket = $listener.AcceptSocket()で接続要求を送ってきた対象とデータの送受信を行うためのソケットを生成します。その後ネットワークストリームからデータを読み出すためのメソッドを持つNetworkStreamクラスの引数に先ほど用意したソケットを渡してオブジェクトを生成します。これで送られてきたデータを読みだす準備が整いました。なお11行目のStreamWriterクラスを生成せずともNetworkStreamクラスのメソッドやプロパティを利用してデータの書き込みができそうだったのですが、検証する時間が取れなかったので今回は暫定的に使い慣れているStreamWriterクラスを利用しています。
データの受信と入力した値の送信
15行目~28行目に記載してある内容の大部分については前回の「【Powershell】TCPクライアントの作り方」の記事で解説してるので、詳細が知りたい方は冒頭で紹介した記事を確認ください。今回は受け取ったデータを表示し、Read-Hostコマンドレットで入力したデータを送信するだけなので基本的な内容になっています。前回の記事の解説が理解できれば今回も問題なく読み進められるでしょう。