@@ -493,11 +493,17 @@ This is the server side::
493493
494494 def handle(self):
495495 # self.request is the TCP socket connected to the client
496- self.data = self.request.recv(1024).strip()
497- print("Received from {}:".format(self.client_address[0]))
498- print(self.data)
496+ pieces = [b'']
497+ total = 0
498+ while b'\n' not in pieces[-1] and total < 10_000:
499+ pieces.append(self.request.recv(2000))
500+ total += len(pieces[-1])
501+ self.data = b''.join(pieces)
502+ print(f"Received from {self.client_address[0]}:")
503+ print(self.data.decode("utf-8"))
499504 # just send back the same data, but upper-cased
500505 self.request.sendall(self.data.upper())
506+ # after we return, the socket will be closed.
501507
502508 if __name__ == "__main__":
503509 HOST, PORT = "localhost", 9999
@@ -514,20 +520,24 @@ objects that simplify communication by providing the standard file interface)::
514520 class MyTCPHandler(socketserver.StreamRequestHandler):
515521
516522 def handle(self):
517- # self.rfile is a file-like object created by the handler;
518- # we can now use e.g. readline() instead of raw recv() calls
519- self.data = self.rfile.readline().strip()
520- print("{} wrote:".format(self.client_address[0]))
521- print(self.data)
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+ # We limit ourselves to 10000 bytes to avoid abuse by the sender.
526+ self.data = self.rfile.readline(10000).rstrip()
527+ print(f"{self.client_address[0]} wrote:")
528+ print(self.data.decode("utf-8"))
522529 # Likewise, self.wfile is a file-like object used to write back
523530 # to the client
524531 self.wfile.write(self.data.upper())
525532
526533The difference is that the ``readline() `` call in the second handler will call
527534``recv() `` multiple times until it encounters a newline character, while the
528- single ``recv() `` call in the first handler will just return what has been
529- received so far from the client's ``sendall() `` call (typically all of it, but
530- this is not guaranteed by the TCP protocol).
535+ the first handler had to use a ``recv() `` loop to accumulate data until a
536+ newline itself. If it had just used a single ``recv() `` without the loop it
537+ would just have returned what has been received so far from the client.
538+ TCP is stream based: data arrives in the order it was sent, but there no
539+ correlation between client ``send() `` or ``sendall() `` calls and the number
540+ of ``recv() `` calls on the server required to receive it.
531541
532542
533543This is the client side::
@@ -542,13 +552,14 @@ This is the client side::
542552 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
543553 # Connect to server and send data
544554 sock.connect((HOST, PORT))
545- sock.sendall(bytes(data + "\n", "utf-8"))
555+ sock.sendall(bytes(data, "utf-8"))
556+ sock.sendall(b"\n")
546557
547558 # Receive data from the server and shut down
548559 received = str(sock.recv(1024), "utf-8")
549560
550- print("Sent: {}".format( data) )
551- print("Received: {}".format( received) )
561+ print("Sent: ", data)
562+ print("Received:", received)
552563
553564
554565The output of the example should look something like this:
@@ -593,7 +604,7 @@ This is the server side::
593604 def handle(self):
594605 data = self.request[0].strip()
595606 socket = self.request[1]
596- print("{} wrote:".format( self.client_address[0]) )
607+ print(f"{ self.client_address[0]} wrote:" )
597608 print(data)
598609 socket.sendto(data.upper(), self.client_address)
599610
@@ -618,8 +629,8 @@ This is the client side::
618629 sock.sendto(bytes(data + "\n", "utf-8"), (HOST, PORT))
619630 received = str(sock.recv(1024), "utf-8")
620631
621- print("Sent: {}".format( data) )
622- print("Received: {}".format( received) )
632+ print("Sent: ", data)
633+ print("Received:", received)
623634
624635The output of the example should look exactly like for the TCP server example.
625636
0 commit comments