简体   繁体   English

Python套接字接收多个TCP标头

[英]Python Socket Receive for multiple TCP headers

I am a beginner with Python, so please consider I will not be able to give complete information in one go. 我是Python的初学者,所以请考虑我一口气也无法提供完整的信息。

My requirements are: 我的要求是:

I am implementing a Python based socket receiver. 我正在实现一个基于Python的套接字接收器。 Implementation is complete but I have to handle a message/data stream with following: 实现已完成,但我必须通过以下方式处理消息/数据流:

1) Data stream will have 4 different types of message in it. 1)数据流中将包含4种不同类型的消息。 Each having a message header (1-4) which I am getting using 每个都有我正在使用的消息头(1-4)

type_msg=struct.unpack('B',data[0])[0]

2) Second part is that next 4 bits will have the actual length of the data of each type according to the header. 2)第二部分是接下来的4位将根据标头具有每种类型的数据的实际长度。 So, 所以,

actual_len = struct.unpack('i', data[1:5])[0]

3) Next part is to handle the data received and play with it. 3)接下来的部分是处理接收到的数据并进行处理。 Length of received data can be taken by ** rcv_len = len(data)** 接收数据的长度可以通过** rcv_len = len(data)**获取

I am facing problem in situation where I receive less/more data then than actual length. 在接收到的数据少于实际长度的情况下,我遇到了问题。 I have the delta-length which I have got using actual_len-rcv_len 我有使用Actual_len-rcv_len获得增量长度

I am unable to handle code after this. 此后,我无法处理代码。 What is the best way to receive delta message and then appending it to received data till now. 到目前为止,接收增量消息并将其附加到接收到的数据中的最佳方法是什么。 I also want to write the data into a file. 我也想将数据写入文件。

I have read about data.append but not very sure about how to implement it. 我已经阅读了有关data.append的信息,但对如何实现它不太确定。 Should I again receive data using conn.recv(del_len) or do something else. 我应该再次使用conn.recv(del_len)接收数据还是执行其他操作?

Any guidance will be very helpful. 任何指导都将非常有帮助。

Adding Code below: 在下面添加代码:

BUFFER_SIZE=40960
import socket
import struct

class mySocket:

def __init__(self, sock=None):
    if sock is None:
        self.sock = socket.socket(
                        socket.AF_INET, socket.SOCK_STREAM)
        self.sock.bind(('', 9988)) 
        self.sock.listen(1)
    else:
        self.sock = sock

def receive_data(self):
    # Wait for a connection
    print >>sys.stderr, 'waiting for a connection'
    conn, client_address= self.sock.accept()
    print "Connected to client with IP---->", client_address
    while True:
        data = conn.recv(BUFFER_SIZE) 
        if not data:
            print "Connection is Broken.."
            break
        else: 
            if data<5:
                print "MSG HEADER STILL NOT COMPLETELY RECEIVED"
            else:
                type_msg=struct.unpack('B',data[0])
                msg_type = type_msg[0]
                rcv_len = len(data)
                actual_len = struct.unpack('i', data[1:5])[0]
                print "Received Length: ",rcv_len
                print "Actual Length : ",actual_len
                if msg_type == 1:
                    f_cfg = open("test.xml", "wb")
                    if rcv_len < actual_len:
                        del_len = actual_len-rcv_len
                        print "Delta length :",del_len
                        while (del_len):
                            print "Receiving Falcon Config File..."
                            print "Actual Length : ",actual_len,"and total length now is",rcv_len+del_len
                            f_cfg.write(data[5:rcv_len]+data[del_len]) //Feel something wrong in this.
                    else:
                        print "Writing Falcon config"
                        f_cfg.write(data[5:])
                    f_cfg.close()
                else:
                    print "INVALID MESSAGE TYPE. DATA CORRUPTED !!"
                    break

    conn.send("Data Received")
    conn.close()

You are pretty close. 你很亲密 The tricks are to never read in more data than you need at any step so you don't have to worry about over shooting. 诀窍是在任何步骤中都不会读取比您所需更多的数据,因此您不必担心过度拍摄。 And just keep track of the data remaining by subtracting the amount you receive each time so you don't have to juggle multiple variables. 并且只需减去每次收到的金额就可以跟踪剩余数据,因此您不必处理多个变量。

Here is a helper that will read in a fixed size buffer. 这是一个将读取固定大小缓冲区的帮助程序。 Use it to read in the header. 用它读入标题。

def recv_exactly(sock, count):
    """receive exactly count bytes from socket. If socket is closed,
    empty string is returned even if some data received.
    """
    buf = []
    while count:
        data = sock.recv(count)
        if not data:
            return ''
        count -= len(data)
        buf.append(data)
    return ''.join(buf)

You could use the same function to read in the data, but its better to write the file as you go. 您可以使用相同的函数来读取数据,但是最好随手编写文件。 Notice when receiving data, the min function is used to decide on a recv size. 注意,接收数据时, min函数用于确定接收大小。

def receive_data(self):
    # Wait for a connection
    print >>sys.stderr, 'waiting for a connection'
    conn, client_address= self.sock.accept()
    print "Connected to client with IP---->", client_address
    while True:
        # read fix length header
        data = recv_exactly(conn, 5) 
        if not data:
            print "Connection is Broken.."
            break
        msg_type, data_len = struct.unpack('Bi', data)

        if msg_type == 1:
            # read stream into file
            with open('test.xml', 'wb') as fp:
                while data_len:
                    # read next chunk. on the last chunk, limit recv to the
                    # known amount of outstanding data
                    data = conn.recv(min(data_len, BUFFER_SIZE))
                    if not data:
                        print "ERROR: TOO FEW BYTES RECEIVED"
                        break
                    fp.write(data)
                    data_len -= len(data)

    conn.send("Data Received")
    conn.close()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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