classMyTCPHandler(socketserver.BaseRequestHandler): """ The request handler class for our server. It is instantiated once per connection to the server, and must override the handle() method to implement communication to the client. """
defhandle(self): # self.request is the TCP socket connected to the client self.data = self.request.recv(1024).strip() print("{} wrote:".format(self.client_address[0])) print(self.data) # just send back the same data, but upper-cased self.request.sendall(self.data.upper())
if __name__ == "__main__": HOST, PORT = "localhost", 9999
# Create the server, binding to localhost on port 9999 with socketserver.TCPServer((HOST, PORT), MyTCPHandler) as server: # Activate the server; this will keep running until you # interrupt the program with Ctrl-C server.serve_forever()
tcp_client.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
import socket import sys
HOST, PORT = "localhost", 9999 data = " ".join(sys.argv[1:])
# Create a socket (SOCK_STREAM means a TCP socket) with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: # Connect to server and send data sock.connect((HOST, PORT)) sock.sendall(bytes(data + "\n", "utf-8"))
# Receive data from the server and shut down received = str(sock.recv(1024), "utf-8")
classMyUDPHandler(socketserver.BaseRequestHandler): """ This class works similar to the TCP handler class, except that self.request consists of a pair of data and client socket, and since there is no connection the client address must be given explicitly when sending data back via sendto(). """
if __name__ == "__main__": HOST, PORT = "localhost", 9999 with socketserver.UDPServer((HOST, PORT), MyUDPHandler) as server: server.serve_forever()
udp_client.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
import socket import sys
HOST, PORT = "localhost", 9999 data = " ".join(sys.argv[1:])
# SOCK_DGRAM is the socket type to use for UDP sockets sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# As you can see, there is no connect() call; UDP has no connections. # Instead, data is directly sent to the recipient via sendto(). sock.sendto(bytes(data + "\n", "utf-8"), (HOST, PORT)) received = str(sock.recv(1024), "utf-8")
""" a minimal socket server refer https://docs.python.org/3/library/socket.html """
# Copyright (c) 2020. John Lyu
import socket import logging
_logger = logging.getLogger()
classMyBaseServer(): """ refer to https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html > The Open Group Base Specifications Issue 7, 2018 edition > IEEE Std 1003.1-2017 (Revision of IEEE Std 1003.1-2008) > SOCK_STREAM > Provides sequenced, reliable, bidirectional, connection-mode byte streams, and may provide a transmission mechanism for out-of-band data. > SOCK_DGRAM > Provides datagrams, which are connectionless-mode, unreliable messages of fixed maximum length. A TCP connection is in fact a socket which use SOCK_STREAM type. """
classMyTCPServer(mysocketserver.MyBaseServer): """Documents for MyTCPServer""" SOCKET_TYPE = socket.SOCK_STREAM
def__init__(self, address_port): """Constructor for MyTCPServer""" super(MyTCPServer, self).__init__(address_port)
defactive_server(self): self.socket.listen(0)
defserve_forever(self): whileTrue: try: conn, addr = self.socket.accept() except KeyboardInterrupt as ex: break except Exception as ex: break if conn: with conn: self.handle(conn, addr)
defhandle(self, request, client_address): # self.request is the TCP socket connected to the client data = request.recv(1024) # max length is 1024
print("{} wrote:".format(client_address[0])) print(data) # just send back the same data, but upper-cased request.sendall(data.upper()[::-1]) self.shutdown_request(request)
defshutdown_request(self, request): """Called to shutdown and close an individual request.""" try: #explicitly shutdown. socket.close() merely releases #the socket and waits for GC to perform the actual close. request.shutdown(socket.SHUT_WR) except OSError: pass#some platforms may raise ENOTCONN here
if __name__ == "__main__": HOST, PORT = "localhost", 9999
# Create the server, binding to localhost on port 9999 with MyTCPServer((HOST, PORT)) as server: # Activate the server; this will keep running until you # interrupt the program with Ctrl-C server.serve_forever()
defhandle(self, request, client_address): # self.request is the UDP socket connected to the client data = request # max length is 1024
print("{} wrote:".format(client_address[0])) print(data) # just send back the same data, but upper-cased self.socket.sendto(data.upper()[::-1], client_address)
if __name__ == "__main__": HOST, PORT = "localhost", 9999
# Create the server, binding to localhost on port 9999 with MyUDPServer((HOST, PORT)) as server: # Activate the server; this will keep running until you # interrupt the program with Ctrl-C server.serve_forever()
import socket import time from multiprocessing import Pool
HOST, PORT = "localhost", 9999
deftcp_send(data): # Create a socket (SOCK_STREAM means a TCP socket) with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: # Connect to server and send data sock.connect((HOST, PORT)) time.sleep(5) data = str(data) sock.sendall(bytes(data, "utf-8")) # Receive data from the server and shut down received = str(sock.recv(1024), "utf-8")
# Connect to server and send data sock.connect((HOST, PORT)) data = str(data) sock.sendall(bytes(data, "utf-8")) # Receive data from the server and shut down received = str(sock.recv(1024), "utf-8")
# send for sleep time.sleep(3) sock.sendall(bytes(data, "utf-8")) # 在tcp_server中也需要添加对应的receive
for sock in read_sockets: if sock == self.socket: sockfd, addr = self.socket.accept() sockfd.setblocking(0) self.connection_list.append(sockfd) self.message_queues[sockfd] = Queue() print(f"[{datetime.datetime.now()}] Client {addr} connected")
# Some incoming message from a client else: # Data recieved from client, process it try: # In Windows, sometimes when a TCP program closes abruptly, # a "Connection reset by peer" exception will be thrown data = sock.recv(1024) if data == ''and sock in self.write_list: self.write_list.remove(sock) if sock notin self.write_list: print(f"[{datetime.datetime.now()}] get data: {data}") self.message_queues[sock].put(data) self.write_list.append(sock)
# client disconnected, so remove from socket list except Exception as ex: # print(ex) print(f"[{datetime.datetime.now()}] Client {addr} is offline") sock.close() self.connection_list.remove(sock) del self.message_queues[sock]
for sock in write_sockets: sname = id(sock) data = self.message_queues[sock].get_nowait() sock.sendall(data) self.write_list.remove(sock)