socketはネットワーク通信に利用するファイルの一種。
そして、このソケットに紐づけられた「ファイルディスクリプタ」を用いることで、アプリケーションに対してデータを送ることができる。
ファイルディスクリプタとは、プログラムが利用する標準入出力やファイル入出力をOSが識別するための識別子です。
### サーバサイド
1. socket()作成
2. bindはsocketをローカルのアドレスにバインド
3. listen()は接続を待ち受け
4. accept()は外部からの接続に対して新しいソケットをサック製
5. send()/receive()でデータの送受信
6. close()でソケットクローズ
### クライアントサイド
1. socket()でソケット作成
2. connect()はリモートソケットに接続
3. send()/receive()でデータの送受信
5. close()でソケットクローズ、ファイルディスクリプタ削除
### ソケット通信のバリエーション/パラメータ
ソケット通信の方式を決めるためのパラメータは、主に(1)アドレスファミリー、(2)ソケットタイプ
(1)アドレスファミリー
ソケットにバインドするアドレスの種類
・AF_UNIX: ローカル通信に使用する。同一マシン間でプロセス間通信を可能とする。
・AF_INET: IPv4インターネットプロトコル, TCP
・AF_INET6: IPv6インターネットプロトコル, TCP
(2)socket Type
TCPであればSOCK_STREAM, UDPであればSOCK_DGRAM
・SOCK_STREAM: 双方向のバイトストリーム
・SOCK_DGRAM: データグラム、UDPソケットで利用
import os import socket class BlockingServerBase: def __init__(self, timeout:int=60, buffer:int=1024): self.__socket = None self.__timeout = timeout self.__buffer = buffer self.close() def __del__(self): self.close() def close(self) -> None: try: self.__socket.shutdown(socket.SHUT_RDWR) self.__socket.close() except: pass def accept(self, address, family:int, type:int, proto:int) -> None: self.__socket = socket.socket(family, typ, proto) self.__socket.settimeout(self.__timeout) self.__socket.bind(address) self.__socket.listen(1) print("Server started:", address) conn, _ = self.__socket.accept() while True: try: message_recv = conn.recv(self.__buffer).decode('utf-8') message_resp = self.respond(message_recv) conn.send(message_resp.encode('utf-8')) except ConnectionResetError: break except BrokenPipeError: break self.close() def respond(self.message:str) -> str: return ""
import socket class BaseClient: def __init__(self, timeout:int=10, buffer:int=1024) self.__socket = None self.__address = None self.__timeout = timeout self.__buffer = buffer def connect(self, address, family:int, typ:int, proto:int): self.__address = address self.__socket = socket.socket(family, typ, proto) self.__socket.settimeout(self.__timeout) self.__socket.connect(self.__address) def send(self, message:str="") -> None: flag = False while True: if message == "": message_send = input("> ") else: message_send=messsage flag = True self.__socket.send(message_send.encode('utf-8')) message_recv = self.__socket.recv(self.__buffer).decode('utf-8') self.received(message_recv) if flag: break try: self.__socket.shutdown(socket.SHUT_RDWR) self.__socket.close() except: pass def received(self, message:str): print(message)