@@ -499,11 +499,17 @@ This is the server side::
499499
500500 def handle(self):
501501 # self.request is the TCP socket connected to the client
502- self.data = self.request.recv(1024).strip()
503- print("Received from {}:".format(self.client_address[0]))
504- print(self.data)
502+ pieces = [b'']
503+ total = 0
504+ while b'\n' not in pieces[-1] and total < 10_000:
505+ pieces.append(self.request.recv(2000))
506+ total += len(pieces[-1])
507+ self.data = b''.join(pieces)
508+ print(f"Received from {self.client_address[0]}:")
509+ print(self.data.decode("utf-8"))
505510 # just send back the same data, but upper-cased
506511 self.request.sendall(self.data.upper())
512+ # after we return, the socket will be closed.
507513
508514 if __name__ == "__main__":
509515 HOST, PORT = "localhost", 9999
@@ -520,20 +526,24 @@ objects that simplify communication by providing the standard file interface)::
520526 class MyTCPHandler(socketserver.StreamRequestHandler):
521527
522528 def handle(self):
523- # self.rfile is a file-like object created by the handler;
524- # we can now use e.g. readline() instead of raw recv() calls
525- self.data = self.rfile.readline().strip()
526- print("{} wrote:".format(self.client_address[0]))
527- print(self.data)
529+ # self.rfile is a file-like object created by the handler.
530+ # We can now use e.g. readline() instead of raw recv() calls.
531+ # We limit ourselves to 10000 bytes to avoid abuse by the sender.
532+ self.data = self.rfile.readline(10000).rstrip()
533+ print(f"{self.client_address[0]} wrote:")
534+ print(self.data.decode("utf-8"))
528535 # Likewise, self.wfile is a file-like object used to write back
529536 # to the client
530537 self.wfile.write(self.data.upper())
531538
532539The difference is that the ``readline() `` call in the second handler will call
533540``recv() `` multiple times until it encounters a newline character, while the
534- single ``recv() `` call in the first handler will just return what has been
535- received so far from the client's ``sendall() `` call (typically all of it, but
536- this is not guaranteed by the TCP protocol).
541+ the first handler had to use a ``recv() `` loop to accumulate data until a
542+ newline itself. If it had just used a single ``recv() `` without the loop it
543+ would just have returned what has been received so far from the client.
544+ TCP is stream based: data arrives in the order it was sent, but there no
545+ correlation between client ``send() `` or ``sendall() `` calls and the number
546+ of ``recv() `` calls on the server required to receive it.
537547
538548
539549This is the client side::
@@ -548,13 +558,14 @@ This is the client side::
548558 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
549559 # Connect to server and send data
550560 sock.connect((HOST, PORT))
551- sock.sendall(bytes(data + "\n", "utf-8"))
561+ sock.sendall(bytes(data, "utf-8"))
562+ sock.sendall(b"\n")
552563
553564 # Receive data from the server and shut down
554565 received = str(sock.recv(1024), "utf-8")
555566
556- print("Sent: {}".format( data) )
557- print("Received: {}".format( received) )
567+ print("Sent: ", data)
568+ print("Received:", received)
558569
559570
560571The output of the example should look something like this:
@@ -599,7 +610,7 @@ This is the server side::
599610 def handle(self):
600611 data = self.request[0].strip()
601612 socket = self.request[1]
602- print("{} wrote:".format( self.client_address[0]) )
613+ print(f"{ self.client_address[0]} wrote:" )
603614 print(data)
604615 socket.sendto(data.upper(), self.client_address)
605616
@@ -624,8 +635,8 @@ This is the client side::
624635 sock.sendto(bytes(data + "\n", "utf-8"), (HOST, PORT))
625636 received = str(sock.recv(1024), "utf-8")
626637
627- print("Sent: {}".format( data) )
628- print("Received: {}".format( received) )
638+ print("Sent: ", data)
639+ print("Received:", received)
629640
630641The output of the example should look exactly like for the TCP server example.
631642
0 commit comments