From 272de5b80982013bdaec8fc84aad504142006389 Mon Sep 17 00:00:00 2001 From: talcs Date: Tue, 14 Nov 2023 13:58:27 +0200 Subject: [PATCH 1/8] Update socketserver.rst documentation - an example where TCP handler can handle many requests over the same connection, --- Doc/library/socketserver.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Doc/library/socketserver.rst b/Doc/library/socketserver.rst index 5fd213fa613c8d..d6bfda57da13f7 100644 --- a/Doc/library/socketserver.rst +++ b/Doc/library/socketserver.rst @@ -528,6 +528,24 @@ The difference is that the ``readline()`` call in the second handler will call single ``recv()`` call in the first handler will just return what has been sent from the client in one ``sendall()`` call. +The handlers presented above close the connection after handling a single request. +It is possible, however, to keep the connection open to handle many requests, +until the client hangs up:: + + class MyTCPHandler(socketserver.BaseRequestHandler): + + def handle(self): + while True: + # self.request is the TCP socket connected to the client + self.data = self.request.recv(1024) + # `socket.recv` indicates that the client has hung up by returning 0 bytes + if len(self.data) == 0: + return + 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()) + This is the client side:: From 8028b11669074a8a6b4fecbe5d50208eef25dd95 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Date: Fri, 12 Jan 2024 22:44:50 +0000 Subject: [PATCH 2/8] whitespace --- Doc/library/socketserver.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/socketserver.rst b/Doc/library/socketserver.rst index d6bfda57da13f7..86fbb571bea2b2 100644 --- a/Doc/library/socketserver.rst +++ b/Doc/library/socketserver.rst @@ -528,8 +528,8 @@ The difference is that the ``readline()`` call in the second handler will call single ``recv()`` call in the first handler will just return what has been sent from the client in one ``sendall()`` call. -The handlers presented above close the connection after handling a single request. -It is possible, however, to keep the connection open to handle many requests, +The handlers presented above close the connection after handling a single request. +It is possible, however, to keep the connection open to handle many requests, until the client hangs up:: class MyTCPHandler(socketserver.BaseRequestHandler): From 6828277c60d41b48bf110c1aa226f0262063b415 Mon Sep 17 00:00:00 2001 From: talcs Date: Tue, 20 Feb 2024 11:30:51 +0200 Subject: [PATCH 3/8] Update Doc/library/socketserver.rst Co-authored-by: Serhiy Storchaka --- Doc/library/socketserver.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/socketserver.rst b/Doc/library/socketserver.rst index 86fbb571bea2b2..3d9f86f614f97b 100644 --- a/Doc/library/socketserver.rst +++ b/Doc/library/socketserver.rst @@ -539,7 +539,7 @@ until the client hangs up:: # self.request is the TCP socket connected to the client self.data = self.request.recv(1024) # `socket.recv` indicates that the client has hung up by returning 0 bytes - if len(self.data) == 0: + if not self.data: return print("{} wrote:".format(self.client_address[0])) print(self.data) From 8dfe64ab5e586aab682eabf624172ee01091ea25 Mon Sep 17 00:00:00 2001 From: talcs Date: Tue, 20 Feb 2024 11:36:20 +0200 Subject: [PATCH 4/8] Added while loop to the existing handler example --- Doc/library/socketserver.rst | 35 +++++++++++------------------------ 1 file changed, 11 insertions(+), 24 deletions(-) diff --git a/Doc/library/socketserver.rst b/Doc/library/socketserver.rst index 3d9f86f614f97b..25d760aa343c22 100644 --- a/Doc/library/socketserver.rst +++ b/Doc/library/socketserver.rst @@ -492,12 +492,17 @@ This is the server side:: """ def handle(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()) + while True: + # self.request is the TCP socket connected to the client + self.data = self.request.recv(1024) + if not self.data: + # Client has hung up + break + self.data = self.data.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 @@ -528,24 +533,6 @@ The difference is that the ``readline()`` call in the second handler will call single ``recv()`` call in the first handler will just return what has been sent from the client in one ``sendall()`` call. -The handlers presented above close the connection after handling a single request. -It is possible, however, to keep the connection open to handle many requests, -until the client hangs up:: - - class MyTCPHandler(socketserver.BaseRequestHandler): - - def handle(self): - while True: - # self.request is the TCP socket connected to the client - self.data = self.request.recv(1024) - # `socket.recv` indicates that the client has hung up by returning 0 bytes - if not self.data: - return - 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()) - This is the client side:: From d92bebbb60811307113c89ce209dd74035712300 Mon Sep 17 00:00:00 2001 From: talcs Date: Tue, 20 Feb 2024 11:42:42 +0200 Subject: [PATCH 5/8] updating readline example too --- Doc/library/socketserver.rst | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Doc/library/socketserver.rst b/Doc/library/socketserver.rst index 25d760aa343c22..bff857d0e9f502 100644 --- a/Doc/library/socketserver.rst +++ b/Doc/library/socketserver.rst @@ -519,9 +519,14 @@ objects that simplify communication by providing the standard file interface):: class MyTCPHandler(socketserver.StreamRequestHandler): def handle(self): - # self.rfile is a file-like object created by the handler; - # we can now use e.g. readline() instead of raw recv() calls - self.data = self.rfile.readline().strip() + while True: + # self.rfile is a file-like object created by the handler; + # we can now use e.g. readline() instead of raw recv() calls + self.data = self.rfile.readline() + if not self.data: + # Client has hung up + break + self.data = self.data.strip() print("{} wrote:".format(self.client_address[0])) print(self.data) # Likewise, self.wfile is a file-like object used to write back From 93c7d86fa487e35123489ae930de4a9e76c88edf Mon Sep 17 00:00:00 2001 From: talcs Date: Tue, 20 Feb 2024 11:52:41 +0200 Subject: [PATCH 6/8] solved conflicts --- Doc/library/socketserver.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/socketserver.rst b/Doc/library/socketserver.rst index bff857d0e9f502..dfd1dfcdc2daee 100644 --- a/Doc/library/socketserver.rst +++ b/Doc/library/socketserver.rst @@ -499,7 +499,7 @@ This is the server side:: # Client has hung up break self.data = self.data.strip() - print("{} wrote:".format(self.client_address[0])) + print("Received from {}:".format(self.client_address[0])) print(self.data) # just send back the same data, but upper-cased self.request.sendall(self.data.upper()) @@ -527,7 +527,7 @@ objects that simplify communication by providing the standard file interface):: # Client has hung up break self.data = self.data.strip() - print("{} wrote:".format(self.client_address[0])) + print("Received from {}:".format(self.client_address[0])) print(self.data) # Likewise, self.wfile is a file-like object used to write back # to the client From 9c6ad3c610eff1a06d5e20dfb188ff7ac9e80b37 Mon Sep 17 00:00:00 2001 From: talcs Date: Wed, 21 Feb 2024 13:12:08 +0200 Subject: [PATCH 7/8] fix while loops in handler --- Doc/library/socketserver.rst | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/Doc/library/socketserver.rst b/Doc/library/socketserver.rst index dfd1dfcdc2daee..70d26dae8a1829 100644 --- a/Doc/library/socketserver.rst +++ b/Doc/library/socketserver.rst @@ -492,17 +492,15 @@ This is the server side:: """ def handle(self): - while True: - # self.request is the TCP socket connected to the client - self.data = self.request.recv(1024) - if not self.data: - # Client has hung up - break + # self.request is the TCP socket connected to the client + self.data = self.request.recv(1024) + while self.data: self.data = self.data.strip() print("Received from {}:".format(self.client_address[0])) print(self.data) # just send back the same data, but upper-cased self.request.sendall(self.data.upper()) + self.data = self.request.recv(1024) if __name__ == "__main__": HOST, PORT = "localhost", 9999 @@ -519,19 +517,17 @@ objects that simplify communication by providing the standard file interface):: class MyTCPHandler(socketserver.StreamRequestHandler): def handle(self): - while True: - # self.rfile is a file-like object created by the handler; - # we can now use e.g. readline() instead of raw recv() calls + # self.rfile is a file-like object created by the handler; + # we can now use e.g. readline() instead of raw recv() calls + self.data = self.rfile.readline() + while self.data: + self.data = self.data.strip() + print("Received from {}:".format(self.client_address[0])) + print(self.data) + # Likewise, self.wfile is a file-like object used to write back + # to the client + self.wfile.write(self.data.upper()) self.data = self.rfile.readline() - if not self.data: - # Client has hung up - break - self.data = self.data.strip() - print("Received from {}:".format(self.client_address[0])) - print(self.data) - # Likewise, self.wfile is a file-like object used to write back - # to the client - self.wfile.write(self.data.upper()) The difference is that the ``readline()`` call in the second handler will call ``recv()`` multiple times until it encounters a newline character, while the From d860d46848c2a7d3d402ae5c9410d3b741fb1706 Mon Sep 17 00:00:00 2001 From: talcs Date: Wed, 21 Feb 2024 13:19:27 +0200 Subject: [PATCH 8/8] Update socketserver.rst --- Doc/library/socketserver.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Doc/library/socketserver.rst b/Doc/library/socketserver.rst index 70d26dae8a1829..2cf0f4915a7cb2 100644 --- a/Doc/library/socketserver.rst +++ b/Doc/library/socketserver.rst @@ -500,6 +500,8 @@ This is the server side:: print(self.data) # just send back the same data, but upper-cased self.request.sendall(self.data.upper()) + # Receive next message from client. Will return an empty message + # if client has hung up self.data = self.request.recv(1024) if __name__ == "__main__": @@ -527,6 +529,8 @@ objects that simplify communication by providing the standard file interface):: # Likewise, self.wfile is a file-like object used to write back # to the client self.wfile.write(self.data.upper()) + # Receive next message from client. Will return an empty message + # if client has hung up self.data = self.rfile.readline() The difference is that the ``readline()`` call in the second handler will call