1. 程式人生 > >Python socket收發檔案以及二進位制檔案打包

Python socket收發檔案以及二進位制檔案打包

Python socket介紹

Python 二進位制檔案處理

收發二進位制檔案

client

#-*-coding:utf-8-*-

import socket 
import os
import sys
import struct

# data of socket and file datapath 
ADDR = ('127.0.0.1',10086)
BUFSIZE = 1024
filename = 'test1.ui'
FILEINFO_SIZE=struct.calcsize('128s32sI8s')

# 客戶端傳送檔案
def Send_File_Client
():
sendSock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) sendSock.connect(ADDR) fhead=struct.pack('128s11I',filename,0,0,0,0,0,0,0,0,os.stat(filename).st_size,0,0) sendSock.send(fhead) fp = open(filename,'rb') while 1: filedata = fp.read(BUFSIZE) if not filedata: break
sendSock.send(filedata) print u"檔案傳送完畢,正在斷開連線...\n" fp.close() sendSock.close() print u"連線已關閉...\n" if __name__ == '__main__': Send_File_Client()

Server

#-*-coding:utf-8-*-

import socket 
import struct

# data of socket and file datapath 
ADDR = ('127.0.0.1',10086)
BUFSIZE = 1024
FILEINFO_SIZE=struct.calcsize('128s32sI8s') # 接受檔案的伺服器端 def Reveiver_File_Server(): recvSock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) recvSock.bind(ADDR) recvSock.listen(20) print u"等待連線...\n" conn,addr = recvSock.accept() print u"客戶端已連線—> \n",addr fhead = conn.recv(FILEINFO_SIZE) filename,temp1,filesize,temp2=struct.unpack('128s32sI8s',fhead) print filename,temp1,filesize,temp2 print filename,len(filename),type(filename) print filesize filename = 'new_'+filename.strip('\00') #... fp = open(filename,'wb') restsize = filesize print u"正在接收檔案... \n", while 1: if restsize > BUFSIZE: filedata = conn.recv(BUFSIZE) else: filedata = conn.recv(restsize) if not filedata: break fp.write(filedata) restsize = restsize-len(filedata) if restsize == 0: break print u"接收檔案完畢,正在斷開連線...\n" fp.close() conn.close() recvSock.close() print u"連線已關閉...\n" if __name__ == '__main__': Reveiver_File_Server()

通過對client和server的組合使用 可以實現A->B->C甚至更長的傳輸鏈,filename = ‘test1.ui’ 檔案也可以是.exe的可執行檔案

A->B->C 跨中轉站檔案socket傳輸

A.py

#-*-coding:utf-8-*-
import socket
import os
import struct
import time

IP='172.25.105.31'
ADDR = (IP,21567)
BUFSIZE = 1024
filename = 'python.exe'
FILEINFO_SIZE=struct.calcsize('128s32sI8s')

# 客戶端傳送檔案
def Send_File_Client():
    sendSock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    sendSock.connect(ADDR)

    fhead=struct.pack('128s11I',filename,0,0,0,0,0,0,0,0,os.stat(filename).st_size,0,0)
    sendSock.send(fhead)
    fp = open(filename,'rb')
    print u'開始傳送檔案 ',time.time()
    while 1:
        filedata = fp.read(BUFSIZE)
        if not filedata:
            break
        sendSock.send(filedata)
    print u"檔案傳送完畢,正在斷開連線...\n"

    fp.close()
    sendSock.close()
    print u"連線已關閉...\n"

if __name__ == '__main__':
    data=raw_input(u'請輸入中轉電腦的IP地址>')
    if not data:
        print u'IP地址為空結束程式'
    else:
        print u'IP輸入有效,預設連線該IP的21567埠'
        IP=data
        Send_File_Client()

B.py

#-*-coding:utf-8-*-
import socket
import struct
import os

LOCALHOST='172.25.105.31'
TARGET=''
ADDR = (LOCALHOST,21567)
BUFSIZE = 1024
FILEINFO_SIZE=struct.calcsize('128s32sI8s')

# 接受檔案的伺服器端
def Reveiver_File_Server():

    recvSock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    recvSock.bind(ADDR)
    recvSock.listen(20)
    print u"等待連線...\n"

    conn,addr = recvSock.accept()
    print u"客戶端已連線—> \n",addr

    fhead = conn.recv(FILEINFO_SIZE)
    filename,temp1,filesize,temp2=struct.unpack('128s32sI8s',fhead)
    filename = 'temp_'+filename.strip('\00')
    fp = open(filename,'wb')
    restsize = filesize
    print u"正在接收檔案... \n",

    while 1:
        if restsize > BUFSIZE:
            filedata = conn.recv(BUFSIZE)
        else:
            filedata = conn.recv(restsize)
        if not filedata:
            break
        fp.write(filedata)
        restsize = restsize-len(filedata)
        if restsize == 0:
            break
    print u"接收檔案完畢,正在轉發檔案\n"
    print u"關閉當前連線...\n"
    fp.close()
    conn.close()
    recvSock.close()
    Send_File_Client()



def Send_File_Client():
    global TARGET
    ADDR = (TARGET,21568)
    BUFSIZE = 1024
    filename = 'temp_python.exe'
    FILEINFO_SIZE=struct.calcsize('128s32sI8s')
    sendSock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    sendSock.connect(ADDR)
    fhead=struct.pack('128s11I',filename,0,0,0,0,0,0,0,0,os.stat(filename).st_size,0,0)
    sendSock.send(fhead)
    fp = open(filename,'rb')

    while 1:
        filedata = fp.read(BUFSIZE)
        if not filedata:
            break
        sendSock.send(filedata)
    print u"檔案轉發完畢,正在斷開連線...\n"

    fp.close()
    sendSock.close()
    print u"連線已關閉...\n"

if __name__ == '__main__':
    data=raw_input(u'請輸入當前電腦在區域網中的IP地址>')
    if not data:
        print u'IP地址為空結束程式'
    else:
        LOCALHOST=data
        print u'IP輸入有效,預設連線本機的21567埠'
        data=raw_input(u'請輸入目標電腦的IP地址>')
        if not data:
            print u'目標電腦IP地址為空,程式結束'
        else:
            print u'目標電腦IP有效,預設使用目標電腦的21568埠'
            TARGET=data
            Reveiver_File_Server()

C.py

#-*-coding:utf-8-*-
import time
import socket
import struct

LOCALHOST='172.20.112.142'
ADDR = (LOCALHOST,21568)
BUFSIZE = 1024
FILEINFO_SIZE=struct.calcsize('128s32sI8s')

# 接受檔案的伺服器端
def Reveiver_File_Server():
    recvSock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    recvSock.bind(ADDR)
    recvSock.listen(20)
    print u"等待連線...\n"

    conn,addr = recvSock.accept()
    print u"客戶端已連線—> \n",addr

    fhead = conn.recv(FILEINFO_SIZE)
    filename,temp1,filesize,temp2=struct.unpack('128s32sI8s',fhead)
    print filename,temp1,filesize,temp2
    print filename,len(filename),type(filename)
    print filesize

    filename = 'new_'+filename.strip('\00')
    fp = open(filename,'wb')
    restsize = filesize
    print u"正在接收檔案... \n",

    while 1:
        if restsize > BUFSIZE:
            filedata = conn.recv(BUFSIZE)
        else:
            filedata = conn.recv(restsize)
        if not filedata:
            break
        fp.write(filedata)
        restsize = restsize-len(filedata)
        if restsize == 0:
            break
    print u"接收檔案完畢\n"
    print time.time()
    fp.close()
    conn.close()
    recvSock.close()
    print u"連線已關閉...\n"

if __name__ == '__main__':
    data=raw_input(u'請輸入本機在區域網中的IP地址>')
    if not data:
        print u'輸入的IP地址為空,程式結束'
    else:
        print u'當前電腦IP地址有效,預設使用21568埠'
        LOCALHOST=data
        Reveiver_File_Server()

上面三個檔案分別執行在三個主機上,A主機上有一個python.exe的Python安裝檔案,先執行B和C,在執行A 檔案從A讀取檔案 B中轉 最後發給C ;每個主機的IP要配置其在區域網中的IP,不要配置成127.0.0.1