多執行緒 TCP 套接字伺服器
當沒有引數執行時,該程式啟動一個 TCP 套接字伺服器,該伺服器偵聽埠 5000
上與 127.0.0.1
的連線。伺服器在單獨的執行緒中處理每個連線。
使用 -c
引數執行時,此程式將連線到伺服器,讀取客戶端列表並將其列印出來。客戶端列表作為 JSON 字串傳輸。可以通過傳遞 -n
引數來指定客戶端名稱。通過傳遞不同的名稱,可以觀察到對客戶列表的影響。
client_list.py
import argparse
import json
import socket
import threading
def handle_client(client_list, conn, address):
name = conn.recv(1024)
entry = dict(zip(['name', 'address', 'port'], [name, address[0], address[1]]))
client_list[name] = entry
conn.sendall(json.dumps(client_list))
conn.shutdown(socket.SHUT_RDWR)
conn.close()
def server(client_list):
print "Starting server..."
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('127.0.0.1', 5000))
s.listen(5)
while True:
(conn, address) = s.accept()
t = threading.Thread(target=handle_client, args=(client_list, conn, address))
t.daemon = True
t.start()
def client(name):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', 5000))
s.send(name)
data = s.recv(1024)
result = json.loads(data)
print json.dumps(result, indent=4)
def parse_arguments():
parser = argparse.ArgumentParser()
parser.add_argument('-c', dest='client', action='store_true')
parser.add_argument('-n', dest='name', type=str, default='name')
result = parser.parse_args()
return result
def main():
client_list = dict()
args = parse_arguments()
if args.client:
client(args.name)
else:
try:
server(client_list)
except KeyboardInterrupt:
print "Keyboard interrupt"
if __name__ == '__main__':
main()
伺服器輸出
$ python client_list.py
Starting server...
客戶輸出
$ python client_list.py -c -n name1
{
"name1": {
"address": "127.0.0.1",
"port": 62210,
"name": "name1"
}
}
接收緩衝區限制為 1024 位元組。如果客戶端列表的 JSON 字串表示超出此大小,則將截斷該表示。這將導致引發以下異常:
ValueError: Unterminated string starting at: line 1 column 1023 (char 1022)