python网络编程客户端向服务器传送图片的步骤

客户端

连接端部分

首先还是先创建TCP套接字

socket.AF_INET表示使用IPv4地址,

socket.SOCK_STREAM表示使用TCP协议进行通信。

socket.socket(socket.AF_INET, socket.SOCK_STREAM)
通过scoket对象连接服务器IP地址和端口
server_socket.bind((“”, 8000))

图片部分

 struct.pack()函数打包要发送的文件信息, 

格式字符串b'128sq'

128s表示一个长度为128字节的字符串,q表示一个长整型数

bytes(os.path.basename(filepath), encoding='utf-8')将文件名转换为utf-8编码的字节对象

os.stat(filepath).st_size获取文件的大小。

filepath = input('input the file:')

fead = struct.pack(b'128sq', bytes(os.path.basename(filepath), encoding='utf-8'),os.stat(filepath).st_size)
  1. s.send(fead):使用socket对象s将打包好的文件信息发送到服务器。

  2. fp = open(filepath, 'rb'):以二进制读取模式打开用户指定的文件,创建一个文件对象fp

  3. while True::进入一个无限循环,直到文件读取完毕。

  4. data = fp.read(1024):从文件对象fp中读取1024字节(1KB)的数据,并将其保存在变量data中。

  5. if not data::如果读取的数据为空,说明文件已经读取完毕,跳出循环。

  6. s.send(data):使用socket对象s将读取的数据发送到服务器。

  7. print('{0} send over...'.format(filepath)):打印传输完成的文件名。

  8. s.close():关闭客户端的socket连接。

        s.send(fead)

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

代码例子:

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(('192.168.9.145', 8888))
        except socket.error as msg:
            print(msg)
            print(sys.exit(1))

        filepath = input('input the file:')
        fead = struct.pack(b'128sq', bytes(os.path.basename(filepath), encoding='utf-8'),
                           os.stat(filepath).st_size)

        s.send(fead)

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


if __name__ == '__main__':
    sock_client_image()

服务端

  1. socket.socket(socket.AF_INET, socket.SOCK_STREAM):首先还是先创建TCP套接字

  2. s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1):设置socket选项,使得可以复用绑定的地址和端口。

  3. s.bind(('192.168.56.1', 8888)):连接服务器IP地址和端口

  4. s.listen(10):开始监听客户端连接请求,参数表示可以同时接收的最大连接数。

  5. sys.exit(1)表示通过调用sys模块的exit()函数来终止程序的执行。
  6. sock, addr = s.accept():等待客户端的连接请求,如果有连接请求过来,返回一个新的socket对象sock和客户端的地址信息addr

  7. deal_image(sock, addr):处理图像数据的函数,将接收到的客户端socket对象和地址信息传递给它。

    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind(('192.168.56.1', 8888))
        s.listen(10)
    except socket.error as msg:
        print(msg)
        sys.exit(1)
    
    print('Wait for Connection................')

    while True:
        sock, addr = s.accept()
        deal_image(sock, addr)
  1. file_info_size = struct.calcsize('128sq'):计算打包格式'128sq'的大小,用于接收文件信息。

  2. buf = sock.recv(file_info_size):使用客户端socket对象sock接收指定大小的数据,存储在变量buf中。

  3. filename, filesize = struct.unpack('128sq', buf):使用打包格式'128sq'解析接收到的文件信息,得到文件名和文件大小。

  4. fn = filename.decode().strip('\x00'):将文件名解码为字符串,并去除字符串末尾的空字符。

  5. new_filename = os.path.join('./', 'new_' + fn):生成一个新的文件名,加上前缀new_

  6. fp = open(new_filename, 'wb'):以二进制写入模式打开新的文件,创建一个文件对象fp

  7. while not recd_size == filesize::当已接收文件数据的大小不等于文件大小时。

  8. data = sock.recv(1024):接收1024字节的文件数据,并存储在变量data中。

  9. fp.write(data):将接收到的文件数据写入新的文件。

  10. fp.close():关闭文件对象。

  11. sock.close():关闭客户端socket连接。

  12. break:跳出循环,结束函数。

def deal_image(sock, addr):
    print("Accept connection from {0}".format(addr))

    while True:
        file_info_size = struct.calcsize('128sq')
        buf = sock.recv(file_info_size)

        if buf:
            filename, filesize = struct.unpack('128sq', buf)
            fn = filename.decode().strip('\x00')
            new_filename = os.path.join('./', 'new_' + fn)

            recd_size = 0
            fp = open(new_filename, 'wb')
            while not recd_size == filesize:
                if filesize - recd_size > 1024:
                    data = sock.recv(1024)
                    recd_size += len(data)
                else:
                    data = sock.recv(1024)
                    recd_size = filesize

                fp.write(data)
            fp.close()
        sock.close()
        break


if __name__ == '__main__':
    socket_service_image()

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值