@@ -493,11 +493,17 @@ This is the server side::
493
493
494
494
def handle(self):
495
495
# 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"))
499
504
# just send back the same data, but upper-cased
500
505
self.request.sendall(self.data.upper())
506
+ # after we return, the socket will be closed.
501
507
502
508
if __name__ == "__main__":
503
509
HOST, PORT = "localhost", 9999
@@ -514,20 +520,24 @@ objects that simplify communication by providing the standard file interface)::
514
520
class MyTCPHandler(socketserver.StreamRequestHandler):
515
521
516
522
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"))
522
529
# Likewise, self.wfile is a file-like object used to write back
523
530
# to the client
524
531
self.wfile.write(self.data.upper())
525
532
526
533
The difference is that the ``readline() `` call in the second handler will call
527
534
``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.
531
541
532
542
533
543
This is the client side::
@@ -542,13 +552,14 @@ This is the client side::
542
552
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
543
553
# Connect to server and send data
544
554
sock.connect((HOST, PORT))
545
- sock.sendall(bytes(data + "\n", "utf-8"))
555
+ sock.sendall(bytes(data, "utf-8"))
556
+ sock.sendall(b"\n")
546
557
547
558
# Receive data from the server and shut down
548
559
received = str(sock.recv(1024), "utf-8")
549
560
550
- print("Sent: {}".format( data) )
551
- print("Received: {}".format( received) )
561
+ print("Sent: ", data)
562
+ print("Received:", received)
552
563
553
564
554
565
The output of the example should look something like this:
@@ -593,7 +604,7 @@ This is the server side::
593
604
def handle(self):
594
605
data = self.request[0].strip()
595
606
socket = self.request[1]
596
- print("{} wrote:".format( self.client_address[0]) )
607
+ print(f"{ self.client_address[0]} wrote:" )
597
608
print(data)
598
609
socket.sendto(data.upper(), self.client_address)
599
610
@@ -618,8 +629,8 @@ This is the client side::
618
629
sock.sendto(bytes(data + "\n", "utf-8"), (HOST, PORT))
619
630
received = str(sock.recv(1024), "utf-8")
620
631
621
- print("Sent: {}".format( data) )
622
- print("Received: {}".format( received) )
632
+ print("Sent: ", data)
633
+ print("Received:", received)
623
634
624
635
The output of the example should look exactly like for the TCP server example.
625
636
0 commit comments