@@ -461,6 +461,21 @@ def connect(
461
461
raise MMQTTException (exc_msg ) from last_exception
462
462
raise MMQTTException (exc_msg )
463
463
464
+ def _send_bytes (
465
+ self ,
466
+ buffer : Union [bytes , bytearray , memoryview ],
467
+ ):
468
+ bytes_sent : int = 0
469
+ bytes_to_send = len (buffer )
470
+ view = memoryview (buffer )
471
+ while bytes_sent < bytes_to_send :
472
+ try :
473
+ bytes_sent += self ._sock .send (view [bytes_sent :])
474
+ except OSError as exc :
475
+ if exc .errno == EAGAIN :
476
+ continue
477
+ raise
478
+
464
479
def _connect ( # noqa: PLR0912, PLR0915, Too many branches, Too many statements
465
480
self ,
466
481
clean_session : bool = True ,
@@ -529,8 +544,8 @@ def _connect( # noqa: PLR0912, PLR0915, Too many branches, Too many statements
529
544
self .logger .debug ("Sending CONNECT to broker..." )
530
545
self .logger .debug (f"Fixed Header: { fixed_header } " )
531
546
self .logger .debug (f"Variable Header: { var_header } " )
532
- self ._sock . send (fixed_header )
533
- self ._sock . send (var_header )
547
+ self ._send_bytes (fixed_header )
548
+ self ._send_bytes (var_header )
534
549
# [MQTT-3.1.3-4]
535
550
self ._send_str (self .client_id )
536
551
if self ._lw_topic :
@@ -591,7 +606,7 @@ def disconnect(self) -> None:
591
606
self ._connected ()
592
607
self .logger .debug ("Sending DISCONNECT packet to broker" )
593
608
try :
594
- self ._sock . send (MQTT_DISCONNECT )
609
+ self ._send_bytes (MQTT_DISCONNECT )
595
610
except (MemoryError , OSError , RuntimeError ) as e :
596
611
self .logger .warning (f"Unable to send DISCONNECT packet: { e } " )
597
612
self ._close_socket ()
@@ -608,7 +623,7 @@ def ping(self) -> list[int]:
608
623
"""
609
624
self ._connected ()
610
625
self .logger .debug ("Sending PINGREQ" )
611
- self ._sock . send (MQTT_PINGREQ )
626
+ self ._send_bytes (MQTT_PINGREQ )
612
627
ping_timeout = self .keep_alive
613
628
stamp = ticks_ms ()
614
629
@@ -683,9 +698,9 @@ def publish( # noqa: PLR0912, Too many branches
683
698
qos ,
684
699
retain ,
685
700
)
686
- self ._sock . send (pub_hdr_fixed )
687
- self ._sock . send (pub_hdr_var )
688
- self ._sock . send (msg )
701
+ self ._send_bytes (pub_hdr_fixed )
702
+ self ._send_bytes (pub_hdr_var )
703
+ self ._send_bytes (msg )
689
704
self ._last_msg_sent_timestamp = ticks_ms ()
690
705
if qos == 0 and self .on_publish is not None :
691
706
self .on_publish (self , self .user_data , topic , self ._pid )
@@ -749,12 +764,12 @@ def subscribe( # noqa: PLR0912, PLR0915, Too many branches, Too many statements
749
764
packet_length += sum (len (topic .encode ("utf-8" )) for topic , qos in topics )
750
765
self ._encode_remaining_length (fixed_header , remaining_length = packet_length )
751
766
self .logger .debug (f"Fixed Header: { fixed_header } " )
752
- self ._sock . send (fixed_header )
767
+ self ._send_bytes (fixed_header )
753
768
self ._pid = self ._pid + 1 if self ._pid < 0xFFFF else 1
754
769
packet_id_bytes = self ._pid .to_bytes (2 , "big" )
755
770
var_header = packet_id_bytes
756
771
self .logger .debug (f"Variable Header: { var_header } " )
757
- self ._sock . send (var_header )
772
+ self ._send_bytes (var_header )
758
773
# attaching topic and QOS level to the packet
759
774
payload = b""
760
775
for t , q in topics :
@@ -764,7 +779,7 @@ def subscribe( # noqa: PLR0912, PLR0915, Too many branches, Too many statements
764
779
for t , q in topics :
765
780
self .logger .debug (f"SUBSCRIBING to topic { t } with QoS { q } " )
766
781
self .logger .debug (f"payload: { payload } " )
767
- self ._sock . send (payload )
782
+ self ._send_bytes (payload )
768
783
stamp = ticks_ms ()
769
784
self ._last_msg_sent_timestamp = stamp
770
785
while True :
@@ -829,19 +844,19 @@ def unsubscribe( # noqa: PLR0912, Too many branches
829
844
packet_length += sum (len (topic .encode ("utf-8" )) for topic in topics )
830
845
self ._encode_remaining_length (fixed_header , remaining_length = packet_length )
831
846
self .logger .debug (f"Fixed Header: { fixed_header } " )
832
- self ._sock . send (fixed_header )
847
+ self ._send_bytes (fixed_header )
833
848
self ._pid = self ._pid + 1 if self ._pid < 0xFFFF else 1
834
849
packet_id_bytes = self ._pid .to_bytes (2 , "big" )
835
850
var_header = packet_id_bytes
836
851
self .logger .debug (f"Variable Header: { var_header } " )
837
- self ._sock . send (var_header )
852
+ self ._send_bytes (var_header )
838
853
payload = b""
839
854
for t in topics :
840
855
topic_size = len (t .encode ("utf-8" )).to_bytes (2 , "big" )
841
856
payload += topic_size + t .encode ()
842
857
for t in topics :
843
858
self .logger .debug (f"UNSUBSCRIBING from topic { t } " )
844
- self ._sock . send (payload )
859
+ self ._send_bytes (payload )
845
860
self ._last_msg_sent_timestamp = ticks_ms ()
846
861
self .logger .debug ("Waiting for UNSUBACK..." )
847
862
while True :
@@ -1028,7 +1043,7 @@ def _wait_for_msg( # noqa: PLR0912, Too many branches
1028
1043
if res [0 ] & 0x06 == 0x02 :
1029
1044
pkt = bytearray (b"\x40 \x02 \0 \0 " )
1030
1045
struct .pack_into ("!H" , pkt , 2 , pid )
1031
- self ._sock . send (pkt )
1046
+ self ._send_bytes (pkt )
1032
1047
elif res [0 ] & 6 == 4 :
1033
1048
assert 0
1034
1049
@@ -1109,11 +1124,11 @@ def _send_str(self, string: str) -> None:
1109
1124
1110
1125
"""
1111
1126
if isinstance (string , str ):
1112
- self ._sock . send (struct .pack ("!H" , len (string .encode ("utf-8" ))))
1113
- self ._sock . send (str .encode (string , "utf-8" ))
1127
+ self ._send_bytes (struct .pack ("!H" , len (string .encode ("utf-8" ))))
1128
+ self ._send_bytes (str .encode (string , "utf-8" ))
1114
1129
else :
1115
- self ._sock . send (struct .pack ("!H" , len (string )))
1116
- self ._sock . send (string )
1130
+ self ._send_bytes (struct .pack ("!H" , len (string )))
1131
+ self ._send_bytes (string )
1117
1132
1118
1133
@staticmethod
1119
1134
def _valid_topic (topic : str ) -> None :
0 commit comments