R
R
Roman2016-11-17 21:46:20
Python
Roman, 2016-11-17 21:46:20

Why does the socket module in python truncate data on receive regardless of the parameter in the recv function?

Hello!
There is a server script and a client script that communicate via socket. Connected through a router. The problem is that on Windows the client works fine, but the same client code on ubuntu, regardless of the parameter of the recv function, cuts off the data that is sent from the server! Moreover, a change from recv(1024), for example, to recv(8192) does not give any changes, pieces of the same size come.
The data sent is about 17 kB.

There are two more reservations:
1) on Windows, the same problem occurs if you connect the client computer not via a cable to the router, but via wi-fi.
And if through a cable, then everything is fine! The server in both cases is connected to the router via wi-fi.
With this, ubuntu always has such a problem.

2) the client is part of a GUI application implemented in pyqt, I don't think that's the point, but still...

Client:

def exchange_data(self, a, timeout=None):
        """Send commands to server and receive the answer from it"""

        host = self.open_config()
        port = 9090
        
        gateway = socket.socket()
        gateway.settimeout(timeout)  # set response timeout
        gateway.connect((host, port))
        gateway.send(bytes(a, encoding = "utf-8"))

        data = gateway.recv(1024)
        log = gateway.recv(32768)     # именно этот кусок данных независимо от параметра обрезается на ubuntu
        gateway.close()
        return data, log


Server:
port = 9090
sock = socket.socket()
# create a socket
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  # reuse a local socket if it busy
sock.bind(('', port))  

while True:
    print('Receiving...')
    sock.listen(1)
    conn, addr = sock.accept()
    try:
        data = conn.recv(1024)
        print("recive data: ", data)
        # welcome
        if data == b"conn":
            conn.send(b'ok')
            conn.close()
        
        elif data == b"some_command":
            os.system("python script.py {}".format(data.decode("utf-8")))   # decode a byte to string in command
            # send data when it appear
            while True:
                # send values
                with open("values", "rb") as f:
                    values= f.read()
                    if len(values) > 3:
                        conn.send(values)
                        # send other values
                        with open("other_values", "rb") as lg:
                            log = lg.read()
                            if len(log) > 3:
                                conn.send(log)
                                conn.close()
                                break
    except Exception:
        continue

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Alexey Cheremisin, 2016-11-17
@ZinBu

You're just getting the information wrong. If you look at the description of the recv function, then it returns the actually received data, which can be cut. In your case, you need to receive data in a loop until the desired length is reached. Better yet, make a header that will store the length of the packet, first you receive the header, then in a loop you receive data to the desired length. TCP guarantees that the data will not be mixed up and will arrive sequentially, but the protocol does not guarantee that the data will arrive in exactly the same chunks that it was sent with.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question