简体   繁体   中英

Python Sockets - Sending a packet to a server and waiting for a response

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:

Server is just an echo type

...

Client, from your code with slight changes

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:

revised version by sending single byte

... 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM