Tuesday, June 8, 2021

Working with File I/O in Python

File Wildcards 
-------------- 

 

`glob` 

This module provides a function for making a lists from directory wildcard searches 

>>> import glob 

>>> glob.glob('*.py') 

['primes.py', 'random.py', 'quote.py'] 

 

Working on Binary Data 

---------------------- 

 

`struct` 

Contains `pack()` and `unpack()` functions to loop through header information without using 
`zipfile` module. 

import struct 

 

with open('myfile.zip', 'rb') as f: 

    data = f.read() 

 

start = 0 

for i in range(3):                      # show the first 3 file headers 

    start += 14 

    fields = struct.unpack('<IIIHH', data[start:start+16]) 

    crc32, comp_size, uncomp_size, filenamesize, extra_size = fields 

 

    start += 16 

    filename = data[start:start+filenamesize] 

    start += filenamesize 

    extra = data[start:start+extra_size] 

    print(filename, hex(crc32), comp_size, uncomp_size) 

 

    start += extra_size + comp_size     # skip to the next header 
 
Sample output: 

b'config-err-t6uao6' 0x0 0 0 

b'gnome-software-34B15Y/' 0x0 0 0 

b'gnome-software-GYBW5Y/' 0x0 0 0 

 

Socket 

------ 

 

Basics 

AF_INET - ipv4 address famnily 

STREAM - TCP socket type 

Methods 

socket.gethostname() - returns your computers haostname 

socket.socket() - creates a socket object 

simple client-server connection setup 

1. create server socket 

>>> import socket 

>>> s = socket.socket()  # creates a socket object 

>>> host = socket.gethostname() 

>>> port = 8000 

>>> s.bind((host, port)) 

# puts socket in listening state (queues 5 connections before rejecting others) 

>>> s.listen(5) 

# accepts an incoming connection (returns if a connection was accepted, 

# otherwise; it will just hang) 

>>> conn, addr = s.accept() 

 

2. create client socket 

>>> import socket 

>>> s = socket.socket() 

>>> host = 'remote.system.com' 

>>> port = 8000 

# connects to remote system 

>>> socket.connect((host, port)) 

 

Server's s.accept() and client's s.connect() are peers. If the other 

one is not alive, the other will just hang. For example, if client 

launched s.connect() first before server launches its s.accept(), 

client side will hang and will not return until server launches its 

s.accept(). Same true if the other way around has happened. 

sending and receiving 

1. server 

# continuing the example above, will make our server be able to receive 

# 100 bytes at a time (buffer size). This will return once it received 

# something from the other end. 

>>> conn.recv(100) 

 

2. client 

# To send a string, add `b` so it will be converted into byte type 

>>> s.send(b'Hello world\n') 

# You can also open a file in binary mode and send it. 

>>> f = open('grocery list.txt', 'rb') 

>>> data = f.read() 

>>> f.close() 

>>> s.send(data) 

sending to multiple client sockets 

# Continuing the examplese above, let's create 2 client sockets from the server 

>>> clientsocket1, addr = s.accept() 

# on client1, execute s.connect((host, port)) 

>>> clientsocket2, addr = s.accept() 

# on client2, execute s.connect((host, port)) 

>>> 

# Now, send separate messages to each client using their respective sockets 

>>> clientsocket1.send(b'Hi client1') 

# On client1, do a s.recv(4096) to receive the data 

>>> clientsocket2.send(b'Hi client2') 

# On client2, do a s.recv(4096) to receive the data 

preparing data for transmission 

You can only send data in its binary form. Here are ways on how to do it. 

>>> conn.send(b'I am no longer a string') 

>>> response = 'Hello {}'.format('world') 

>>> conn.send(response.encode('utf-8') 

 

On the receiving end, you can decode the binary data by using .decode: 

>>> received_data = s.recv(1024) 

>>> print(received_data.decode('utf-8')) 

right way of closing connection 

If client calls `close()`, server will receive 0 byte response for every `recv()` calls. 


 

 

Sources: 

No comments:

Post a Comment