socket客户端向服务端传送图片

客户端代码:

improt socket
import os
import sys
import struct

def socck_client_image():
    while True:
        try:
            s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
            s.connect(('127.0.0.1',8888))
        except socket.error as msg:
            print(msg)
            print(sys.exit(1))
        filepath = input('input the file')
        fhead = struct.pack(b'128sq',bytes(os.path.basename(filepath),encoding='utf8')
                            ,os.stat(filepath).st_size)
        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

if __name__ == '__main__':
    socck_client_image()

服务端代码:

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',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)
    
def deal_image(sock,addr):
    print('accept connection from {0}'.format(addr))
    
    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()

导入的模块:

  1. socket 模块的功能是提供网络通信的底层接口。在这段代码中,使用 socket 模块创建了一个套接字对象 s,并使用该套接字对象与服务器建立了 TCP 连接。

  2. os 模块提供了与操作系统交互的功能。在这段代码中,使用 os 模块获取了要发送的文件的信息,包括文件名和文件大小。使用 os.path.basename(filepath) 获取文件名,使用 os.stat(filepath).st_size 获取文件大小。

  3. sys 模块提供了与 Python 解释器交互的功能。在这段代码中,使用 sys.exit(1) 终止程序并返回退出码 1。退出码可以用于在程序执行结束后判断程序的执行状态。

  4. struct 模块用于处理二进制数据的打包和解包。在这段代码中,使用 struct 模块将文件名和文件大小打包成一个二进制数据结构,用于发送给服务器。

运用的几个核心的函数:

  1. socket.socket():创建一个套接字对象。通过指定的地址族(socket.AF_INET 表示IPv4)、套接字类型(socket.SOCK_STREAM 表示TCP套接字)来创建一个套接字对象,并将其赋值给变量 s

  2. s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1):设置套接字选项,允许地址重用。这样可以在套接字关闭后立即重启服务器,而不需要等待一段时间以释放端口。

  3. s.bind:将套接字绑定到指定的IP地址和端口号。这里使用 0.0.0.0 表示绑定到所有网络接口上,并监听端口号为 9999 的连接请求。

  4. s.listen(10):开始监听连接请求,参数 10 表示同时允许最多处理 10 个连接请求等待队列。

  5. sock.recv(size):从已连接的套接字 sock 接收数据,其中 size 是要接收的最大数据量(字节数)。返回接收到的数据。在 deal_image() 函数中,该函数用于接收文件信息和文件数据。

  6. struct.calcsize(format):根据给定的格式字符串 format 计算结构体的大小(字节数)。在这里,用于计算接收文件信息所占用的字节数。

  7. struct.unpack(format, buffer):根据给定的格式字符串 format 解包二进制数据 buffer,返回一个元组。在这里,用于解包接收到的文件信息,得到文件名和文件大小。

  8. socket.connect(('192.168.126.66', 9999)):与服务器建立TCP连接。通过socket.connect()方法连接到指定的服务器IP地址和端口号,这里连接的是IP地址为'192.168.126.66',端口号为9999的服务器。

  9. struct.pack(b'128sq', bytes(os.path.basename(filepath), encoding='utf8'), os.stat(filepath).st_size):将文件名和文件大小打包成一个二进制数据结构。使用struct.pack()函数将文件名和文件大小打包为一个二进制数据结构。b'128sq'是打包格式,128s表示长度为128字节的字符串,q表示一个64位整数。

  10. open(filepath, 'rb'):以二进制只读模式打开要发送的文件。使用open()函数以二进制只读模式打开用户输入的文件路径。

  11. fp.read(1024):从打开的文件对象fp中读取数据。每次最多读取1024字节的数据。

  12. s.send(data):通过套接字将读取的数据发送给服务器。使用send()方法将读取的数据发送给服务器。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,这是一个关于网络编程的问题。实现客户端上传图片服务端并接收上传成功的消息,可以使用Socket进行实现。 客户端需要先读取本地的client.bmp图片,并将其转换为二进制流,然后通过Socket将二进制流发送到服务端服务端接收到客户端发送的二进制流后,将其保存为server.bmp文件,并向客户端发送上传成功的消息。 以下是一个大致的实现过程: 客户端: 1. 读取本地的client.bmp文件,将其转换为二进制流。 ``` with open('client.bmp', 'rb') as f: data = f.read() ``` 2. 创建Socket连接,并将二进制流发送到服务端。 ``` import socket HOST = '127.0.0.1' # 服务端IP PORT = 8000 # 服务端端口 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((HOST, PORT)) s.sendall(data) response = s.recv(1024) # 接收服务端返回的消息 print(response.decode('utf-8')) # 打印上传成功的消息 s.close() ``` 服务端: 1. 创建Socket连接,接收客户端发送的二进制流,并将其保存为server.bmp文件。 ``` import socket HOST = '127.0.0.1' # 服务端IP PORT = 8000 # 服务端端口 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((HOST, PORT)) s.listen(1) conn, addr = s.accept() print('Connected by', addr) with open('server.bmp', 'wb') as f: while True: data = conn.recv(1024) if not data: break f.write(data) conn.sendall('上传成功'.encode('utf-8')) # 发送上传成功的消息 conn.close() ``` 注意,以上代码只是一个简单的示例,实际使用时还需要考虑一些异常处理和安全性问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值