Elsaの技術日記(徒然なるままに)

主に自分で作ったアプリとかの報告・日記を記載

MENU

pythonでのネットワークサーバ構築とsocket通信

今回はpythonでのtcp通信についてまとめておこうと思います!!
ちょっとやりたいことがあって調べていたので、それをまとめておくことが目的。



■socket通信とは?

socket通信とは、サーバとクライアントを仮想的な接続により結んで構成された環境のことを言います。
f:id:Elsammit:20201219180709p:plain

具体的には、インターネットはTCP/IPと呼ぶ通信プロトコルを利用しますが、そのTCP/IPを プログラムから利用するには、プログラムの世界とTCP/IPの世界を結ぶ特別な 出入り口が必要となります。
その出入り口となるのがソケット (Socket)であり、TCP/IPのプログラミング上の大きな特徴となっています。
このため、TCP/IP通信をソケット通信と呼ぶこともあります。

■環境

今回の構成はこちら。
f:id:Elsammit:20201219181004p:plain

ネットワークサーバをRaspberry Pi側に構築し、クライアントをwindows PCを用いました。
(逆の方がよかったかも。。。)

今回はpythonを用いるのですが、バージョンはこちらの通りです。
windows PC側Pythonバージョン:3.7.4
Raspberry PiPythonバージョン:3.7.3

■ネットワークサーバ構築

まずはネットワークサーバの構築を行います!!
socket通信を行うためのネットワークサーバの構築を行うにあたり、
"socketserver"と"socket"が必要になるのであらかじめ、

pip install pycopy-socketserver
or 
pip3 install pycopy-socketserver
pip install sockets
or
pip3 install sockets

でインストールを行っておきます。

ネットワークサーバ構築のコードはこちら。

import socketserver  
import socket  

class TCPHandler(socketserver.BaseRequestHandler):      
    def handle(self):
        print(self.request.recv(1024).strip().decode())
        self.request.send(("hello world").encode("utf-8")) 

HOST = 'hostを設定'
PORT = ポート番号を設定 
socketserver.TCPServer.allow_reuse_address = True
server = socketserver.TCPServer((HOST, PORT), TCPHandler)  

try:
    server.serve_forever()  
except KeyboardInterrupt:
    pass
server.shutdown()
sys.exit()
server = socketserver.TCPServer((HOST, PORT), TCPHandler)  

でサーバの初期設定を行い、

server.serve_forever()  

でサーバとして起動・常駐させます。

そしてデータを受信すると、

    def handle(self):
        print(self.request.recv(1024).strip().decode())
        self.request.send(("hello world").encode("utf-8")) 

がコールされます。
受信されたデータはバイト列になっているため、

self.request.recv(1024).strip().decode()

のようにデコードしております。
さらに、送信するデータもバイト列に変換する必要があるので、

("hello world").encode("utf-8")

というように文字列をエンコードしてから送信しています。
※今回はhello worldを固定で送信するようにしています。

■クライアント側構築

クライアント側では"socket"が必要になるのであらかじめ、

pip install sockets
or
pip3 install sockets

でインストールを行っておきます。
そして、、、コードはこちら。

import socket  

HOST = 'hostを設定'
PORT = ポート番号を設定 
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)  
sock.connect((HOST,PORT))   
sock.send(('Hello Raspberry').encode("utf-8"))  
    
receivedstr=sock.recv(1024)
print(receivedstr.decode())  

まずは初期設定!!

sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)  
sock.connect((HOST,PORT))   

こちらに記載されているのですが、今回はTCPで通信したかったのでSOCK_STREAMを設定。
https://qiita.com/__init__/items/5c89fa5b37b8c5ed32a4

そして、

sock.send(('Hello Raspberry').encode("utf-8"))  

でサーバへバイト列を送信。
今回はHello Raspberryの文字列をバイト列にエンコードして送信しています。

そして、

receivedstr=sock.recv(1024)

により受信したデータをreceivedstrに格納。
データはバイト列なので、文字列にデコードしてprintでログ出力しております。

■動作確認

始めにサーバ側を起動させた後、クライアント側でコードを実行すると、
【サーバ側】

Hello Raspberry

【クライアント側】

hello world

コマンドプロンプト上に表示されればOKです!!

■最後に

今回の技術を応用してやりたいことが実現出来ました!!
やりたいことが出来て満足😆
後で、応用してできたこともまとめておこうと思います!!