@@ -499,11 +499,17 @@ This is the server side::
499
499
500
500
def handle(self):
501
501
# 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"))
505
510
# just send back the same data, but upper-cased
506
511
self.request.sendall(self.data.upper())
512
+ # after we return, the socket will be closed.
507
513
508
514
if __name__ == "__main__":
509
515
HOST, PORT = "localhost", 9999
@@ -520,20 +526,24 @@ objects that simplify communication by providing the standard file interface)::
520
526
class MyTCPHandler(socketserver.StreamRequestHandler):
521
527
522
528
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"))
528
535
# Likewise, self.wfile is a file-like object used to write back
529
536
# to the client
530
537
self.wfile.write(self.data.upper())
531
538
532
539
The difference is that the ``readline() `` call in the second handler will call
533
540
``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.
537
547
538
548
539
549
This is the client side::
@@ -548,13 +558,14 @@ This is the client side::
548
558
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
549
559
# Connect to server and send data
550
560
sock.connect((HOST, PORT))
551
- sock.sendall(bytes(data + "\n", "utf-8"))
561
+ sock.sendall(bytes(data, "utf-8"))
562
+ sock.sendall(b"\n")
552
563
553
564
# Receive data from the server and shut down
554
565
received = str(sock.recv(1024), "utf-8")
555
566
556
- print("Sent: {}".format( data) )
557
- print("Received: {}".format( received) )
567
+ print("Sent: ", data)
568
+ print("Received:", received)
558
569
559
570
560
571
The output of the example should look something like this:
@@ -599,7 +610,7 @@ This is the server side::
599
610
def handle(self):
600
611
data = self.request[0].strip()
601
612
socket = self.request[1]
602
- print("{} wrote:".format( self.client_address[0]) )
613
+ print(f"{ self.client_address[0]} wrote:" )
603
614
print(data)
604
615
socket.sendto(data.upper(), self.client_address)
605
616
@@ -624,8 +635,8 @@ This is the client side::
624
635
sock.sendto(bytes(data + "\n", "utf-8"), (HOST, PORT))
625
636
received = str(sock.recv(1024), "utf-8")
626
637
627
- print("Sent: {}".format( data) )
628
- print("Received: {}".format( received) )
638
+ print("Sent: ", data)
639
+ print("Received:", received)
629
640
630
641
The output of the example should look exactly like for the TCP server example.
631
642
0 commit comments