[英]Python Sockets - Sending a packet to a server and waiting for a response
我目前正在實現以下代碼,以將數據包發送到Parallels PVA XML API 。 我正在嘗試將兩個 XML數據包發送到服務器。 第一個是指定用戶憑據的登錄數據包,第二個是包含有關API請求信息的數據包。 這些數據包應該以空字節\\0
分隔。 通常,服務器會發回多個數據包,第一個數據包是登錄成功的說明,第二個數據包包含有關API請求的信息。
我遇到的問題是似乎第二個數據包沒有被發送。 我得到的唯一響應是第一個說明登錄成功的數據包,但我沒有得到包含有關API請求信息的數據包。 我以為這可能是因為我要發送一個空字節,所以我嘗試在base64中對所有內容進行編碼,但最終得到了相同的結果。
因此在我看來,要么連接已關閉,服務器沒有足夠的時間發送第二個數據包,要么由於空字節而完全忽略了該數據包。
任何幫助或評論將不勝感激。 先感謝您!
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)
請不要故意在數據包中沒有信息,因為它包含敏感信息,並且ip地址被“ [IP_ADDRESS]”故意取代了
問題是,您嘗試一次發送太多字節, \\0
將終止整個消息,因此剩余部分從未發送過。 我模仿了類似的客戶端/服務器,這是響應:
...
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>
...
您會看到, 2packet從未發送過,因為它被空字節終止,消息主體超過131072字節,比第二部分消息主體更長。
因此,要解決此問題,您只需要在每個循環上發送一個字節,那么空字節將僅終止自身,而下一個字節直到可以發送消息末尾為止:
... 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
最多可以獲取131072個字節,但是完全可以讀取1個字節是完全可以的。 如果立即關閉套接字,答復將丟失。 在讀取服務器發送的所有信息之前,必須重復執行recv
。 所有數據包都以\\0
結尾嗎? 然后閱讀,直到獲得期望的數字'\\ 0'。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.