簡體   English   中英

Python套接字-將數據包發送到服務器並等待響應

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM