I am currently implementing the code below to send a packet to . 。 I am trying to send XML packets to the server. XML数据包发送到服务器。 The first one is a login packet that specifies the users credentials, and the second one is a packet containing information about an API request. These packets are supposed to be separated by a null byte \\0
. Normally, the server sends back multiple packets the first one being a clarification that the login was successful, and the second one containing information about the API request.
The problem that i'm having is that it seems like the second packet isn't being sent. The only response that I am getting back is the first packet that clarifies that the login was successful, but i'm not getting back a packet containing information about the API request. I thought that this could be because i'm sending a null byte, so I tried encoding everything in base64, but I ended up at the same result.
So then it seems to me that either the connection is being closed and the server isn't getting enough time to send it's second packet, or the packet is ignored completely because of the null byte.
Any help or comments will be greatly appreciated. Thank you in advance!
import socket
import base64
def client(string):
HOST, PORT = '[IP_ADDRESS]', 4433
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(10)
sock.connect((HOST, PORT))
sock.send(base64.b64encode(string))
reply = sock.recv(131072)
sock.close()
return reply
packet = "<packet></packet>\0<packet></packet>"
print client(packet)
The problem is, you tried to send too many bytes at one time, and \\0
will terminate the whole message, thus the remaining part has never been sent. I've mimic a similar client/server and here is the response:
...
import socket
from time import sleep
def client():
# I change second packet to 2packet for visually distinguish the packets
packet = "<packet></packet>\0<2packet></2packet>"
HOST, PORT = '127.0.0.1', 4433
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(10)
sock.connect((HOST, PORT))
while True:
try:
sock.send(packet)
sleep(1)
# this is the problem here
reply = sock.recv(131072)
if not reply:
break
print "recvd: ", reply
except KeyboardInterrupt:
print "bye"
break
sock.close()
return
client()
recvd: WelcomeOK...<packet></packet> # the null byte teminate the send and skip all remaining message
recvd: OK...<packet></packet>
recvd: OK...<packet></packet>
recvd: OK...<packet></packet>
...
You will see, the 2packet never got sent since it's terminated by the null byte with the message body over 131072 bytes, which is longer than the second part message body.
So to tackle this, you just need to send a single byte on each loop, so null byte will only terminate itself, and your next byte until end of message can be sent:
... previous code
while True:
try:
sock.send(packet)
sleep(1)
reply = sock.recv(1)
if not reply:
break
print "recvd: ", reply
except KeyboardInterrupt:
print "bye"
break
sock.close()
return
client()
recvd: W
recvd: e
recvd: l
recvd: c
recvd: o
recvd: m
recvd: e
recvd: O
recvd: K
recvd: .
recvd: .
recvd: .
recvd: <
recvd: p
recvd: a
recvd: c
recvd: k
recvd: e
recvd: t
recvd: >
recvd: <
recvd: /
recvd: p
recvd: a
recvd: c
recvd: k
recvd: e
recvd: t
recvd: >
recvd: # <== this null byte terminates single byte send
recvd: < # <== and next loop it tries to send the next byte, goal achieved
recvd: 2
recvd: p
recvd: a
recvd: c
recvd: k
recvd: e
recvd: t
recvd: >
recvd: <
...
sock.recv
can get up to 131072 bytes, but it's totally ok that it reads only 1 byte. If you close the socket immediately, the reply gets lost. You have to repeat recv
until you've read all the information the server sends. Are all packets terminated by \\0
? Then read till you get the expected number of '\\0's.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.