79 lines
2.2 KiB
Python
79 lines
2.2 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
Created on Sun Mar 22 10:46:20 2020
|
|
|
|
@author: cpan
|
|
|
|
This client example is for non-blocking demonstation. It is going to hang if
|
|
the server does not send response due to some reasons. E.g. connection dropped.
|
|
While multi-connection non-blocking is essential for server, it is not
|
|
necessary the best choice for the client.
|
|
|
|
"""
|
|
|
|
import sys
|
|
import socket
|
|
import selectors
|
|
import traceback
|
|
|
|
import libclient
|
|
|
|
sel = selectors.DefaultSelector()
|
|
|
|
|
|
def create_request(action, value):
|
|
if action == "search":
|
|
return dict(
|
|
type="text/json",
|
|
encoding="utf-8",
|
|
content=dict(action=action, value=value),
|
|
)
|
|
else:
|
|
return dict(
|
|
type="binary/custom-client-binary-type",
|
|
encoding="binary",
|
|
content=bytes(action + value, encoding="utf-8"),
|
|
)
|
|
|
|
|
|
def start_connection(host, port, request):
|
|
addr = (host, port)
|
|
print("starting connection to", addr)
|
|
# sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
sock = socket.create_connection(addr)
|
|
sock.setblocking(False)
|
|
# sock.connect_ex(addr)
|
|
events = selectors.EVENT_READ | selectors.EVENT_WRITE
|
|
message = libclient.Message(sel, sock, addr, request)
|
|
sel.register(sock, events, data=message)
|
|
|
|
|
|
if len(sys.argv) != 5:
|
|
print("usage:", sys.argv[0], "<host> <port> <action> <value>")
|
|
sys.exit(1)
|
|
|
|
host, port = sys.argv[1], int(sys.argv[2])
|
|
action, value = sys.argv[3], sys.argv[4]
|
|
request = create_request(action, value)
|
|
start_connection(host, port, request)
|
|
|
|
try:
|
|
while True:
|
|
events = sel.select(timeout=1)
|
|
for key, mask in events:
|
|
message = key.data
|
|
try:
|
|
message.process_events(mask)
|
|
except Exception:
|
|
print(
|
|
"main: error: exception for",
|
|
f"{message.addr}:\n{traceback.format_exc()}",
|
|
)
|
|
message.close()
|
|
# Check for a socket being monitored to continue.
|
|
if not sel.get_map():
|
|
break
|
|
except KeyboardInterrupt:
|
|
print("caught keyboard interrupt, exiting")
|
|
finally:
|
|
sel.close() |