Socket 发送短信 服务端 和 客户端

本文展示了如何使用Python的socket库实现一个简单的TCP/IP图像传输服务端和客户端。服务端监听特定IP和端口,接收客户端发送的图像文件信息和数据,保存到本地。客户端则向服务端发送文件头部信息(包含文件名和大小),然后传输文件内容。
摘要由CSDN通过智能技术生成

服务端:

需要导入多个包

  1. import socket:导入socket模块,用于网络通信。
  2. import os:导入os模块,用于文件操作。
  3. import sys:导入sys模块,用于系统相关操作。
  4. import struct:导入struct模块,用于处理数据的打包和解包。
  5. 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(("192.168.9.190", 6666))
            s.listen(10)
        except socket.error as msg:
            print(msg)
            sys.exit(1)

    定义一个函数socket_service_image(),该函数用于创建并监听socket连接。通过socket.socket()创建一个TCP/IP套接字对象s,设置SO_REUSEADDR选项,绑定到本地IP地址"192.168.9.190"和端口号6666,然后调用s.listen(10)开始监听。

  6. print("Wait for Connection.................."):打印输出"Wait for Connection..................",表示等待客户端的连接。

  7.   while True:
            sock, addr = s.accept()  # addr是一个元组(ip,port)
            deal_image(sock, addr)

    使用一个无限循环,调用s.accept()方法等待客户端连接,返回一个新的socket对象sock和客户端地址addr,然后调用deal_image()函数处理图像数据。

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

    定义一个函数deal_image(sock, addr),用于处理图像数据。打印输出"Accept connection from {0}",其中{0}会被客户端地址addr替代。

  9.     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

    deal_image()函数中,使用一个无限循环,首先计算文件信息的大小并存储在fileinfo_size变量中,然后从socket接收数据并存入buf中。如果buf非空,则进行解包操作,将文件名和文件大小解包为filenamefilesize。将文件名去除空字符并加上前缀"new_",确定新文件的路径。接着,创建一个空文件,并使用循环接收并写入文件数据,直到接收大小等于文件大小。最后关闭文件和socket连接,并结束循环。

10

if __name__ =='__main__':
    socket_service_image()

判断当前脚本是否作为主程序运行,如果是,则调用socket_service_image()函数启动图片传输服务端。

客户端:

  1. import socket:导入socket模块,用于网络通信。
  2. import os:导入os模块,用于文件操作。
  3. import sys:导入sys模块,用于系统相关操作。
  4. import struct:导入struct模块,用于处理数据的打包和解包。
  5. def sock_client_image():
        while True:
            try:
                s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                s.connect(("192.168.9.190", 6666))  # 服务器和客户端都在一个系统下使用的ip和端口
            except socket.error as msg:
                print(msg)
                print(sys.exit(1))

      定义一个函数sock_client_image(),该函数用于创建并连接到socket服务器。通过socket.socket()创建一个TCP/IP套接字对象s,然后调用s.connect(("192.168.9.190", 6666))与服务器建立连接。

6.

  1. filepath = input("input the file: "):接收用户输入,要求用户输入当前目录下的图片名,将其存储在filepath变量中。

7.

fhead = struct.pack(b'128sq', bytes(os.path.basename(filepath), encoding='utf-8'),
                    os.stat(filepath).st_size)   # 将xxx.jpg以128sq的格式打包
s.send(fhead)

·使用struct.pack()方法将文件名和文件大小打包为128sq格式的字节流,其中文件名首先使用os.path.basename()获取,然后通过bytes()将其编码为utf-8格式。同时使用os.stat(filepath).st_size获取文件大小,并一起打包为字节流fhead。最后使用s.send(fhead)发送文件头部信息。

8

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

打开指定路径的图片文件,并使用循环读取1024字节的图片数据。如果读取到的数据为空,则表示图片发送完成,打印输出"{0} send over....",其中{0}会被图片路径替代,并跳出循环。否则,继续发送该1024字节的图片数据。最后关闭文件和socket连接。

9

if __name__ == '__main__':
    sock_client_image()

判断当前脚本是否作为主程序运行,如果是,则调用sock_client_image()函数启动图片传输客户端。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值