I am currently implementing the code below to send a packet to Parallels PVA XML API. I am trying to send two XML packets to the server. 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)
Please not that there is no information in the packets on purpose, because it contains sensitive information, and the ip address was replaced by "[IP_ADDRESS]" on purpose
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: <
...