步骤:
客户端:
-
创建Socket连接:客户端使用
socket
模块创建一个套接字(Socket)对象,并指定服务器的IP地址和端口号,以便建立与服务器的连接。 -
打开图片文件:客户端打开本地的图片文件,可以使用
open()
函数来操作文件 -
建立连接:客户端通过套接字对象的
connect()
方法与服务器建立连接。 -
发送图片数据:客户端使用套接字对象的
sendall()
方法将图片数据发送给服务器。可以将图片数据分块发送,确保完整的数据被发送。 -
关闭连接:发送完成后,关闭套接字连接,释放相关资源。
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",端口号)) # 服务器和客户端在不同的系统或不同的主机下时使用的ip和端口.首先要查看服务器所在的系统网卡的ip
s.connect(("192.168.9.100", 6666)) # 服务器和客户端都在一个系统下时使用的ip和端口
except socket.error as msg:
print(msg)
print(sys.exit(1))
# 输入当前目录下的图片名 xxx.jpg
filepath = input("input the file:")
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()
服务端:
-
创建Socket连接:服务端使用
socket
模块创建一个套接字(Socket)对象,并绑定服务器的IP地址和端口号,以便监听客户端的连接请求。 -
监听连接:服务端通过套接字对象的
bind()
方法将套接字与特定的IP地址和端口号绑定,并通过listen()
方法开始监听来自客户端的连接请求。 -
接受连接:服务端使用套接字对象的
accept()
方法接受客户端的连接请求,并返回一个新的套接字和客户端的地址。 -
接收图片数据:服务端使用返回的套接字对象,使用
recv()
方法接收客户端发送的图片数据。可以通过循环接收数据,直到接收完整的图片数据。 -
保存图片数据:服务端将接收到的图片数据保存到服务器本地的文件中。
-
关闭连接:处理完成后,关闭套接字连接,释放相关资源。
import socket
import os
import sys
import struct
def socket_service_image():
try:
# 建立套接字
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# setsockopt()是一个用于设置套接字选项的方法。通过调用这个方法,您可以在套接字层面上对套接字进行各种配置。
# 第一个参数 socket.SOL_SOCKET 指定了要设置选项的套接字级别,即套接字选项所处的层级。在这种情况下,它设置了 SOL_SOCKET,表示套接字选项应该在套接字层面上生效。
# 第二个参数 socket.SO_REUSEADDR 是要设置的具体选项名称。在这种情况下,SO_REUSEADDR 表示开启地址重用选项。
# 第三个参数 1 是要设置的选项值。在这种情况下,设置为 1 表示启用这个选项。
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind(("192.168.9.116", 1567)) # 端口地地址
s.listen(5) # 监听几人访问
# socket.error类型的异常。当发生套接字相关的错误时,异常将被捕获。
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("Accopt 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()