Python使用socket實現簡單的文件傳輸並校驗

       由於工做須要,要在兩臺設備之間進行壓力測試。即A設備不斷往B設備發送文件,B設備接收文件後校驗文件是否正確接收。python

       用Python的socket模塊寫了簡單的Server和Client腳本。Server負責監聽端口,接收Client發來的文件並作MD5校驗,確認接收的文件是否準確無誤。Client端負責向Server發送文件及文件的MD5值。網絡

       文件名經過Client發送特定字符串提取,文件結束符合經過檢測'EOF'字符實現。實際運行過程當中,發現老是會有誤判,把結束符'EOF'錯誤寫入文件了。但願有大神不吝賜教!!socket


Socket_Server.pyide

#!/usr/bin/python
# -*- coding: utf-8 -*-
# Python:          2.7
# Platform:        Linux
# Author:          wucl(wucl-20@163.com)
# Program:         Socket_Server監聽網絡端口,接收Client發來的文件
# Version:         2.0
# History:         2016.1.28
#                  2016.2.1   接收Client發來的文件並作MD5校驗

import socket, time, hashlib, os, base64, re

def CalcMD5(fineName, block_size=64 * 1024):
  with open(fineName, 'rb') as f:
    md5 = hashlib.md5()
    while True:
      data = f.read(block_size)
      if not data:
        break
      md5.update(data)
    retmd5 = md5.hexdigest()
    print(retmd5)
    return retmd5

def main(IP, Port, log, error_log):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((IP, Port))
    s.listen(12)
    print 'Listened on ', socket.gethostname(), Port
    reg = re.compile('filename:(.*?):(.*)::::')

    while True:
        conn, addr = s.accept()
        print(time.ctime(), 'Connected from ', addr)
        recvd = conn.recv(1024)
        if  recvd:
            ss = reg.findall(recvd)
            filename = ss[0][0]
            md5 = ss[0][1]
            f = open(filename, 'wb')
            while True:
                data = conn.recv(1024)
                if not data:
                    break
                if data == 'EOF':
                    f.close()
                    log.write('%s Received %s\n'%(time.ctime(), filename))
                    log.flush()
                    if CalcMD5(filename) == md5:
                        print('%s Received Successfully!\n' %filename)
                    else:
                        error_log.write('%s %s Recevied failed\n'%(time.ctime(), filename))
                        error_log.flush()
                        print(CalcMD5(filename))
                else:
                    f.write(data)
                    f.flush()
            conn.close()
    s.close()


if __name__ == "__main__":
    IP = ''
    Port = 12345
    log = open('log.txt','w+')
    error_log = open('error_log.txt','w+')
    main(IP, Port, log, error_log)

       

Socket_Client.py測試

#!/usr/bin/python
# -*- coding: utf-8 -*-
# Python:          2.7
# Platform:        Linux
# Author:          wucl(wucl-20@163.com)
# Program:         Socket_Client鏈接網絡端,並向網絡端發送文件。
# Version:         2.0
# History:         2016.1.28
#                  2016.2.1    Client向Server端發送文件及文件的MD5值

import socket, hashlib
import time, os, base64, os.path


def CalcMD5(fineName, block_size=64 * 1024):
  with open(fineName, 'rb') as f:
    md5 = hashlib.md5()
    while True:
      data = f.read(block_size)
      if not data:
        break
      md5.update(data)
    retmd5 = md5.hexdigest()
    print(retmd5)
    return retmd5

def SendFile(s, filename):
    print('Sending %s' % filename)
    s.sendall('filename:%s:%s::::'%(filename, CalcMD5(filename)))
    f = open(filename, 'rb')
    while True:
        chunk = f.read(chunksize)
        if not chunk:
            f.close()
            print('%s Successfully Sent %s\n' %(time.ctime(), filename))
            break
        s.sendall(chunk)
    time.sleep(1)
    s.sendall('EOF')
    s.close()

def main(dirname, IP, Port, MB = 1024):
    for filename in os.listdir(dirname):
        if os.path.isfile(filename):
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.connect((IP, Port))
            SendFile(s, filename)


if __name__ == '__main__':
    dirname = '/root/test/'
    IP = '10.88.106.200'
    Port = 12345
    MB = 1024
    chunksize = int(MB*1024*1024)
    main(dirname, IP, Port, MB)
相關文章
相關標籤/搜索