8000 [3.12] gh-112020: Rework socketserver examples to be correct (GH-129741) by miss-islington · Pull Request #129744 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

[3.12] gh-112020: Rework socketserver examples to be correct (GH-129741) #129744

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 6, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
8000
Diff view
45 changes: 28 additions & 17 deletions Doc/library/socketserver.rst
Original file line number Diff line number Diff line change
Expand Up @@ -493,11 +493,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("Received from {}:".format(self.client_address[0]))
print(self.data)
pieces = [b 8000 '']
total = 0
while b'\n' not in pieces[-1] and total < 10_000:
pieces.append(self.request.recv(2000))
total += len(pieces[-1])
self.data = b''.join(pieces)
print(f"Received from {self.client_address[0]}:")
print(self.data.decode("utf-8"))
# just send back the same data, but upper-cased
self.request.sendall(self.data.upper())
# after we return, the socket will be closed.

if __name__ == "__main__":
HOST, PORT = "localhost", 9999
Expand All @@ -514,20 +520,24 @@ 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()
print("{} wrote:".format(self.client_address[0]))
print(self.data)
# self.rfile is a file-like object created by the handler.
# We can now use e.g. readline() instead of raw recv() calls.
# We limit ourselves to 10000 bytes to avoid abuse by the sender.
self.data = self.rfile.readline(10000).rstrip()
print(f"{self.client_address[0]} wrote:")
print(self.data.decode("utf-8"))
# 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
single ``recv()`` call in the first handler will just return what has been
received so far from the client's ``sendall()`` call (typically all of it, but
this is not guaranteed by the TCP protocol).
the first handler had to use a ``recv()`` loop to accumulate data until a
newline itself. If it had just used a single ``recv()`` without the loop it
would just have returned what has been received so far from the client.
TCP is stream based: data arrives in the order it was sent, but there no
correlation between client ``send()`` or ``sendall()`` calls and the number
of ``recv()`` calls on the server required to receive it.


This is the client side::
Expand All @@ -542,13 +552,14 @@ This is the client side::
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"))
sock.sendall(bytes(data, "utf-8"))
sock.sendall(b"\n")

# Receive data from the server and shut down
received = str(sock.recv(1024), "utf-8")

print("Sent: {}".format(data))
print("Received: {}".format(received))
print("Sent: ", data)
print("Received:", received)


The output of the example should look something like this:
Expand Down Expand Up @@ -593,7 +604,7 @@ This is the server side::
def handle(self):
data = self.request[0].strip()
socket = self.request[1]
print("{} wrote:".format(self.client_address[0]))
print(f"{self.client_address[0]} wrote:")
print(data)
socket.sendto(data.upper(), self.client_address)

Expand All @@ -618,8 +629,8 @@ This is the client side::
sock.sendto(bytes(data + "\n", "utf-8"), (HOST, PORT))
received = str(sock.recv(1024), "utf-8")

print("Sent: {}".format(data))
print("Received: {}".format(received))
print("Sent: ", data)
print("Received:", received)

The output of the example should look exactly like for the TCP server example.

Expand Down
Loading
0