from sys import argv
port=int(sys.argv[1]) if len(argv)>1 else 9999
from socket import socket,AF_INET,SOCK_STREAM
sock=socket(AF_INET,SOCK_STREAM)
sock.bind(('localhost',port))
sock.listen(1)
print("listening on port {}".format(port))
s,ad=sock.accept()
try:
print('connection from',ad)
while True:
data=s.recv(1024)
if not data : break
print(data.encode(),end="")
finally:
s.close()
||
ではなく if~else を使った特殊な書き方になる。||
の右辺にも置けない。ここでは(昔ながらの)if not ~
という書き方が必要になる。from sys import argv,stdin
import socket
host=sys.argv[1] if len(argv)>1 else 'localhost'
port=int(sys.argv[2]) if len(argv)>2 else 9999
with socket.create_connection((host,port)) as sock:
for line in stdin:
sock.send(line.encode())
前述のサーバに対する変更箇所のみ示す。
data=s.recv(1024)
if not data : break
print(data.decode(),end='')
標準入力からソケットに流すループ、と、 ソケットから標準出力に流すループ、とが 並行で進むよう改良する。
from sys import argv,stdin
import socket, threading
host=sys.argv[1] if len(argv)>1 else 'localhost'
port=int(sys.argv[2]) if len(argv)>2 else 9999
with socket.create_connection((host,port)) as sock:
def recvLoop():
while True:
data=sock.recv(1024)
if not data : break
print(data.decode(),end="")
threading.Thread(target=recvLoop).start()
print("start...")
for line in stdin:
sock.send(line.encode())
threading.Thread
を新たに使ってメインのスレッドから子スレッドを分岐させる。
上記の双方向クライアントと同様にthreading.Thread
を使ってスレッドの分岐を行う。
from threading import Thread
from sys import argv
port=int(sys.argv[1]) if len(argv)>1 else 9999
from socket import socket,AF_INET,SOCK_STREAM
n=0
import signal
signal.signal(signal.SIGINT,signal.SIG_DFL)
def ans(s):
global n
n+=1
id=n
try:
print('connection from',ad)
s.send("hello I'm server{}\n".format(me).encode())
while True:
data=s.recv(1024)
if not data : break
line="{}: {}".format(id,data.decode())
print(line,end='')
s.send(line.encode())
finally:
s.close()
me=('0.0.0.0',port)
sock=socket(AF_INET,SOCK_STREAM)
sock.bind(me)
sock.listen(1)
print("listening on port {}".format(port))
while True:
s,ad=sock.accept()
Thread(target=ans,args=(s,)).start()
接続数をカウントするための変数n
を、
スレッド処理関数(ここではans)の中と外で共有し、 なおかつ
中での変更を外にも反映させるために、global
宣言をする必要がある。
signal.signal() は、Ctrl-Cによる割り込みでサーバを停止させるために必要。