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)