Reputation: 47
I am trying to send a packet with 20 byte checksum, 10 byte sequence and 482 bytes of a file that it reads from. This is what I have below. How do I send the packet with all that info and how does the server know what is what?
import socket
import hashlib
buffer_size = 482
port = 5900
file = open('helloworld.txt', 'rb')
transfer = file.read(buffer_size)
hash_object = hashlib.sha1(transfer)
checksum = hash_object.hexdigest()
addr = ('localhost', port)
sock = socket.socket()
sock.connect(addr)
print('Connected to', addr)
sock.sendto((checksum + transfer))
file.close()
print("File sent")
sock.close()
sock.send()
Upvotes: 0
Views: 1032
Reputation: 177554
Define a byte-oriented protocol for the TCP data stream. Your "10-byte sequence" data wasn't demonstrated, so I'll make one up for illustration. For example:
Example:
import socket
import hashlib
import struct
import os
buffer_size = 482
port = 8000
transfer = os.urandom(buffer_size) # generate some data
hash_object = hashlib.sha1(transfer)
checksum = hash_object.digest() # digest (not hexdigest) is a 20-byte string.
addr = 'localhost', port
sock = socket.socket()
sock.connect(addr)
print('Connected to', addr)
sock.sendall(struct.pack('>H',buffer_size) + checksum + transfer)
print("File sent")
sock.close()
A receiving server could look like the following. Note that TCP is a byte streaming protocol, so a blocking recv(2048)
could return 0 (socket closed) or 1-2048 bytes. I purposefully picked a small, odd value for receiving to demonstrate that you should buffer reads and extract data according to the protocol. This example doesn't handle if the data stream ends early.
import socket
import struct
import hashlib
class Buffer:
def __init__(self,sock):
self.sock = sock
self.buffer = b''
def get(self,length):
# Make sure enough bytes to satisfy the length requested
# are in the buffer.
while len(self.buffer) < length:
data = self.sock.recv(7)
if not data: break
self.buffer += data
# Split off from the current buffer the bytes requested.
# Keep the remainder for the next request.
rcv,self.buffer = self.buffer[:length],self.buffer[length:]
return rcv
s = socket.socket()
s.bind(('',8000))
s.listen(1)
c,a = s.accept()
buf = Buffer(c)
length = struct.unpack('>H',buf.get(2))[0]
chksm = buf.get(20)
transfer = buf.get(length)
verify = hashlib.sha1(transfer)
print(chksm == verify.digest()) # should be "True"
c.close()
s.close()
Upvotes: 1