Network Data and Network
Errors
Created By Shreen Khalaf
Bytes and Strings
convert a list of such numbers to a byte string by passing them to the bytes()
b = bytes([0, 1, 98, 99, 100])
b = bytes([0, 1, 98, 99, 100])
print(len(b))
print(b)
Created By Shreen Khalaf
Character Strings
Encoding characters means turning a string of real Unicode characters into
bytes that can be sent out into the real world outside your Python program.
The encode() method encodes the string, using the specified encoding. If no
encoding is specified, UTF-8 will be used
Syntax
encode(encoding=encoding, errors=errors)
Parameter Values
encoding Optional. A String specifying the encoding to use. Default is UTF-8
errors Optional. A String specifying the error method. Legal values are:
'ignore' - ignores the characters that cannot be encoded
Created By Shreen Khalaf
'replace' - replaces the character with a questionmark
Character Strings
Decoding byte data means converting a byte string into real characters.
Syntax
Str.decode(encoding='UTF-8',errors='strict')
Created By Shreen Khalaf
struct module
struct module, provides a variety of operations for converting data to and
from popular binary formats.
struct.pack(format, v1, v2, ...)
Return a bytes object containing the values v1, v2, … packed according to the
format string format.
struct.unpack(format, buffer)
which converts the binary data back to Python numbers.
Created By Shreen Khalaf
struct module
import struct
print(struct.pack('<i', 4253))
print(struct.pack('>i', 4253))
formatting code 'i', which uses four bytes to store an integer, and this
leaves the two upper bytes zero for a small number like 4253.
Created By Shreen Khalaf
Framing and Quoting
How to delimit your messages so that the receiver can tell where one
message ends and the next one begins ??
1. The receiver call recv() repeatedly until the call finally returns an empty
string
message = b''
while True:
more = sc.recv(8192) # arbitrary value of 8k
if not more: # socket has closed when recv() returns ''
print('Received zero bytes - end of file')
break
print('Received {} bytes'.format(len(more)))
message += more
Created By Shreen Khalaf
print('Message:\n')
print(message.decode('ascii'))
Server
import socket
sok=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
host=socket.gethostname()
port=12345
serv_add=(host,port)
sok.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sok.bind(serv_add)
print('waiting for client')
sok.listen()
conn,add=sok.accept()
conn.shutdown(socket.SHUT_WR)
msg=b''
while True:
data=conn.recv(16)
if not data:
print('no more data')
break
print(data)
msg=msg+data
Created By Shreen Khalaf
print(msg.decode())
Client
import socket
sok=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
host=socket.gethostname()
port=12345
serv_add=(host,port)
sok.connect(serv_add)
print('Connect to server')
sok.shutdown(socket.SHUT_RD)
sok.sendall('Client: Hello'.encode())
sok.sendall('Client: test send message'.encode())
sok.sendall("Client: End".encode())
print('data Sent')
Created By Shreen Khalaf
How to delimit your messages so that the receiver
can tell where one message ends and the next one
begins ??
2. Use fixed-length messages
def recvall(sock, length):
data = ''
while len(data) < length:
more = sock.recv(length - len(data))
if not more:
raise EOFError('socket closed {} bytes into a {}-byte'
' message'.format(len(data), length))
data += more
return data
Created By Shreen Khalaf
How to delimit your messages so that the receiver
can tell where one message ends and the next one
begins ??
3. Delimit your messages with special characters.
The receiver would wait in a recv() loop until the reply string it was
accumulating finally contained the delimiter indicating the end-of-
message.
4. To prefix each message with its length
The length read and decoded, then
The receiver can enter a loop and call recv() repeatedly until the
whole message has arrived (use recvall(sock, length))
Created By Shreen Khalaf
How to delimit your messages so that the receiver
can tell where one message ends and the next one
begins ??
5. Instead of sending just one, try sending several blocks of data that are
each prefixed with their length.
In Server
header_struct = struct.Struct('!I') # messages up to 2**32 -
1 in length
def get_block(sock):
data = recvall(sock, header_struct.size)
(block_length,) = header_struct.unpack(data)
return recvall(sock, block_length)
Created By Shreen Khalaf
In Client
import socket, struct
header_struct = struct.Struct('!I')
def put_block(sock, message):
block_length = len(message)
sock.send(header_struct.pack(block_length))
sock.send(message)
Created By Shreen Khalaf
Server
def server(address):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(address)
sock.listen(1)
print('Listening at', sock.getsockname())
sc, sockname = sock.accept()
print('Accepted connection from', sockname)
sc.shutdown(socket.SHUT_WR)
while True:
block = get_block(sc)
if not block:
break
print('Block says:', repr(block))
sc.close()
sock.close()
Created By Shreen Khalaf
server(('127.0.0.1',12345))
Recvall Method
import socket, struct
header_struct = struct.Struct('!I') # messages up to 2**32 - 1 in length
def recvall(sock, length):
blocks = []
while length:
block = sock.recv(length)
if not block:
raise EOFError('socket closed with %d bytes left'
' in this block'.format(length))
length -= len(block)
blocks.append(block)
return b''.join(blocks
Created By Shreen Khalaf
Client
def client(address):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(address)
sock.shutdown(socket.SHUT_RD)
put_block(sock, b'Beautiful is better than ugly.')
put_block(sock, b'Explicit is better than implicit.')
put_block(sock, b'Simple is better than complex.')
put_block(sock, b'')
sock.close()
client(('127.0.0.1', 12345))
Created By Shreen Khalaf
repr()
The repr() function returns a printable representation of the given object.
Created By Shreen Khalaf
Created By Shreen Khalaf