2

This code will read data from block device and pack data using struct.pack() and again unpack data using struct.unpack(). This is part of my main socket program. But I am facing an issue in calculating struct size. So I am putting a small code here to demonstrate my problem.

import sys,os
import struct as st

    dev_read_data = os.open("/dev/sdc1",os.O_RDONLY)
    buffer_size = 230400
    offset = 0

    while True:
        data = os.pread(dev_read_data,buffer_size,offset)
        packed_data = st.pack("%dsi" %(len(data)),data,offset) # This statement packs data and assign it to packed_data. Till here code works fine.
        print ('Packed_Data {]'.format(packed_data))
        unpacked_data = st.unpack("%dsi" %(len(data)),packed_data) # This unpacks data successfully.

        offset += buffer_size
        if buffer_size == 10036977152:
            break

Now I want to calculate the size of struct using function:

struct.calcsize(format)

But in this case only one parameter can be passed. So how to get struct size in case of variable length binary string?

I will be very thankful if experts can find some time to answer my query.

galoget
  • 722
  • 9
  • 15
Abhishek Verma
  • 396
  • 4
  • 14
  • The socket connection is automatically doing this job. Why do you use a low-level connection? – dsgdfg Jan 31 '18 at 07:59
  • As socket.recv() don't rec all data at once. So need the struct size and then loop over till size of data rec < struct size. Using python struct in this case because i am sending more than one value to the server_socket.py program. If still its not clear, please let me know i will paste the actual code. Thank you for ur reply. :) – Abhishek Verma Jan 31 '18 at 09:17
  • Low-level socket usage: never exceed buffer memory (1600bytes), necessarily define protocol (first 8 bytes (first 4 bytes index number, post frame number)+body + CRC32), file descriptions at the end of packages. If I were you, I'd direct the device to a stream (I'm sure you'd be less busy). – dsgdfg Feb 01 '18 at 13:07
  • @dsgdfg: Please give an eg for more clarity. Thank you. – Abhishek Verma Feb 02 '18 at 05:55

1 Answers1

0

like this :

import os
import binascii
import zlib

path = "/dev/sdc1"

stat = os.stat(path)
block_SIZE = stat.st_blksize
block_COUNT = os.statvfs(path).f_blocks 



image = file(path,"rb")
indicator = 0

while True :
    try :
        if indicator > 2 : break #if indicator > block_Count : break

        image.seek(indicator*block_SIZE)
        data = image.read(block_SIZE)
        HEX_CRC32 =  binascii.unhexlify(str(hex(zlib.crc32(data) & 0xffffffff))[2:])
        header = binascii.unhexlify(("%010X" % indicator)+("%04x"%block_SIZE))
        """ NOW SEND TO SOCKET
        My_socket.write(header+data+HEX_CRC32)

        check Frame number : first 5 byte
        Data Length        : 2 Byte (block_SIZE)
        Data               : Data content
        CRC32              : 2 Byte (32-bit value)

        Client side : Check CRC32 , get `data[7:-2]` for current block 
        """
        indicator += 1
    except Exception,e :
        """
        very important (if failed,re send packet )
        """
        print e

if indicator > block_Count : break

Not only brake ! Tell to client all packet has ben succesfully send, please close to socket on client side.

dsgdfg
  • 1,492
  • 11
  • 18