VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > temp > 简明python教程 >
  • python基础(30):黏包、socket的其他方法(4)

#1T数据,文件路径和md5值
  •  
  • #为了该报头能传送,需要序列化并且转为bytes
  • head_bytes=bytes(json.dumps(header),encoding='utf-8') #序列化并转成bytes,用于传输
  •  
  • #为了让客户端知道报头的长度,用struck将报头长度这个数字转成固定长度:4个字节
  • head_len_bytes=struct.pack('i',len(head_bytes)) #这4个字节里只包含了一个数字,该数字是报头的长度
  •  
  • #客户端开始发送
  • conn.send(head_len_bytes) #先发报头的长度,4个bytes
  • conn.send(head_bytes) #再发报头的字节格式
  • conn.sendall(文件内容) #然后发真实内容的字节格式
  •  
  • #服务端开始接收
  • head_len_bytes=s.recv(4) #先收报头4个bytes,得到报头长度的字节格式
  • x=struct.unpack('i',head_len_bytes)[0] #提取报头的长度
  •  
  • head_bytes=s.recv(x) #按照报头长度x,收取报头的bytes格式
  • header=json.loads(json.dumps(header)) #提取报头
  •  
  • #最后根据报头的内容提取真实的数据,比如
  • real_data_len=s.recv(header['file_size'])
  • s.recv(real_data_len)
  • struct的详细用法:

    
    	
    1. #_*_coding:utf-8_*_
    2. #http://www.cnblogs.com/coser/archive/2011/12/17/2291160.html
    3. __author__ = 'Linhaifeng'
    4. import struct
    5. import binascii
    6. import ctypes
    7.  
    8. values1 = (1, 'abc'.encode('utf-8'), 2.7)
    9. values2 = ('defg'.encode('utf-8'),101)
    10. s1 = struct.Struct('I3sf')
    11. s2 = struct.Struct('4sI')
    12.  
    13. print(s1.size,s2.size)
    14. prebuffer=ctypes.create_string_buffer(s1.size+s2.size)
    15. print('Before : ',binascii.hexlify(prebuffer))
    16. # t=binascii.hexlify('asdfaf'.encode('utf-8'))
    17. # print(t)
    18.  
    19. s1.pack_into(prebuffer,0,*values1)
    20. s2.pack_into(prebuffer,s1.size,*values2)
    21.  
    22. print('After pack',binascii.hexlify(prebuffer))
    23. print(s1.unpack_from(prebuffer,0))
    24. print(s2.unpack_from(prebuffer,s1.size))
    25.  
    26. s3=struct.Struct('ii')
    27. s3.pack_into(prebuffer,0,123,123)
    28. print('After pack',binascii.hexlify(prebuffer))
    29. print(s3.unpack_from(prebuffer,0))

    (2) 使用struct解决黏包

    借助struct模块,我们知道长度数字可以被转换成一个标准大小的4字节数字。因此可以利用这个特点来预先发送数据长度。

     server:

    
    	
    1. import socket,struct,json
    2. import subprocess
    3. phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    4. phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加
    5.  
    6. phone.bind(('127.0.0.1',8080))
    7.  
    8. phone.listen(5)
    9.  
    10. while True:
    11. conn,addr=phone.accept()
    12. while True:
    13. cmd=conn.recv(1024)
    14. if not cmd:break
    15. print('cmd: %s' %cmd)
    16.  
    17. res=subprocess.Popen(cmd.decode
    
    相关教程