Pythonのsocketとは?

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)