使用文件中的数据发送自定义数据包结构

时间:2017-10-31 23:46:35

标签: python-3.x sockets

我正在尝试发送一个包含20字节校验和,10字节序列和482字节的文件的数据包。这就是我在下面的内容。如何发送包含所有信息的数据包以及服务器如何知道什么是什么?

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()

1 个答案:

答案 0 :(得分:0)

为TCP数据流定义面向字节的协议。你的“10字节序列”数据没有被证明,所以我会举一个例子来说明。例如:

  1. 将传输大小发送为2字节的大端值。
  2. 发送传输数据的20字节SHA1摘要。
  3. 发送转移数据
  4. 示例:

    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()
    

    接收服务器可能如下所示。请注意,TCP是字节流协议,因此阻塞recv(2048)可能返回0(套接字关闭)或1-2048字节。我有目的地为接收选择了一个小的奇数值,以证明你应该根据协议缓冲读取和提取数据。如果数据流提前结束,则此示例无法处理。

    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()