python實現客戶端和服務器端傳輸圖片

問題:以windows做爲客戶端,linux做爲服務器端,進行傳輸圖片python


程序:

'''
Fuction:客戶端發送圖片和數據
Date:2018.9.8
Author:snowking
'''
###客戶端client.py
import socket
import os
import sys
import struct

def sock_client_image():
    while True:
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.connect(('服務器的ip', 6666))  #服務器和客戶端在不一樣的系統或不一樣的主機下時使用的ip和端口,首先要查看服務器所在的系統網卡的ip
            # s.connect(('127.0.0.1', 6666))  #服務器和客戶端都在一個系統下時使用的ip和端口
        except socket.error as msg:
            print(msg)
            print(sys.exit(1))
        filepath = input('input the file: ')   #輸入當前目錄下的圖片名 xxx.jpg
        fhead = struct.pack(b'128sq', bytes(os.path.basename(filepath), encoding='utf-8'), os.stat(filepath).st_size)  #將xxx.jpg以128sq的格式打包
        s.send(fhead)

        fp = open(filepath, 'rb')  #打開要傳輸的圖片
        while True:
            data = fp.read(1024) #讀入圖片數據
            if not data:
                print('{0} send over...'.format(filepath))
                break
            s.send(data)  #以二進制格式發送圖片數據
        s.close()
        # break    #循環發送
   
if __name__ == '__main__':
    sock_client_image()

###服務器端server.py
import socket
import os
import sys
import struct

def socket_service_image():
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        # s.bind(('127.0.0.1', 6666))
        s.bind(('服務器的ip', 6666))
        s.listen(10)
    except socket.error as msg:
        print(msg)
        sys.exit(1)

    print("Wait for Connection.....................")

    while True:
        sock, addr = s.accept()  #addr是一個元組(ip,port)
        deal_image(sock, addr)
def deal_image(sock, addr):
    print("Accept connection from {0}".format(addr))  #查看發送端的ip和端口

    while True:
        fileinfo_size = struct.calcsize('128sq')
        buf = sock.recv(fileinfo_size)   #接收圖片名
        if buf:
            filename, filesize = struct.unpack('128sq', buf)
            fn = filename.decode().strip('\x00')
            new_filename = os.path.join('./', 'new_' + fn)  #在服務器端新建圖片名(能夠不用新建的,直接用原來的也行,只要客戶端和服務器不是同一個系統或接收到的圖片和原圖片不在一個文件夾下)

            recvd_size = 0
            fp = open(new_filename, 'wb')

            while not recvd_size == filesize:
                if filesize - recvd_size > 1024:
                    data = sock.recv(1024)
                    recvd_size += len(data)
                else:
                    data = sock.recv(1024)
                    recvd_size = filesize
                fp.write(data)  #寫入圖片數據
            fp.close()
        sock.close()
        break
        
if __name__ == '__main__':
    socket_service_image()

運行結果:
服務器端:linux

clipboard.png

客戶端:windows

clipboard.png

補充說明:
1.首先在linux系統下運行server.py(python server.py),而後在windows python 終端下運行client.py,在終端輸入當前目錄下要傳輸的圖片名,即heat.jpg,能夠看到在服務器的路徑下出現了new_heat.jpg圖片文件,證實文件傳輸成功。
2.剛開始在參考網上的代碼時出現了各類錯誤,其中在調試時一直出現接收到的圖片數據丟失,打不開圖片,弄懂struct.pack的壓縮格式以後,發現是由於參數設置的問題,原來是128sl,其中l是長整型,超出範圍的話接收到的圖片數據就丟失,故改成q以後範圍變大,可以正常接收圖片。下圖是struct.pack的壓縮格式和數據範圍對應表:服務器

clipboard.png
聲明:該圖表來自https://blog.csdn.net/u011006...socket

相關文章
相關標籤/搜索