我们在传输数据时,经常使用tcp/ip的服务器和客户端模型,很多设备也经常将网口作为硬件接口预留出来。可以使用tcp/ip传输图像、大的文件等,如果图片过大,还会进行拆分传输,接收方根据对应协议进行解包。解包过程中可能会出现tcp粘包现象,所以要根据对应特性进行拆包。本次给大家分享一个小的python传输图像的例子,由于数据量不大,没有粘包的现象,以后会给大家分享一个Qt下使用tcp/ip根据对应协议解析图片的例子。
一般在发送图片数据之前会先将图片的大小等相关数据作为一包数据先发送,结束的时候会再次发送结束的数据包,根据包头与包尾来判断图片接收组包是否完整。
运行环境:ubuntu 14.04
先来一个小流程图:
CLIENT SERVER
SIZE (image size)
---------------------------------->
GOT SIZE
<----------------------------------
send image itself
---------------------------------->
GOT IMAGE
<----------------------------------
BYE BYE
---------------------------------->
server closes socket
1.Python client send image:
try:# open imagemyfile = open(image, 'rb')bytes = myfile.read()size = len(bytes)# send image size to serversock.sendall("SIZE %s" % size)answer = sock.recv(4096)print 'answer = %s' % answer# send image to serverif answer == 'GOT SIZE':sock.sendall(bytes)# check what server sendanswer = sock.recv(4096)print 'answer = %s' % answerif answer == 'GOT IMAGE' :sock.sendall("BYE BYE ")print 'Image successfully send to server'myfile.close()finally:sock.close()
发送图片是客户端,主要是将图片读取为字节,获取字节大小,先发送到服务器端。之后等待服务器应答,服务器向客户端发送'GOT SIZE',表明成功接收到图片大小,之后客户端发送图片字节。这里面主要的就是如何读取图片为字节数据。
2.Python server recv image:
while True:read_sockets, write_sockets, error_sockets = select.select(connected_clients_sockets, [], [])for sock in read_sockets:if sock == server_socket:sockfd, client_address = server_socket.accept()connected_clients_sockets.append(sockfd)else:try:data = sock.recv(4096)txt = str(data)if data:if data.startswith('SIZE'):tmp = txt.split()size = int(tmp[1])print 'got size'sock.sendall("GOT SIZE")elif data.startswith('BYE'):sock.shutdown()else :myfile = open(basename % imgcounter, 'wb')myfile.write(data)data = sock.recv(40960000)if not data:myfile.close()breakmyfile.write(data)myfile.close()sock.sendall("GOT IMAGE")sock.shutdown()except:sock.close()connected_clients_sockets.remove(sock)continueimgcounter += 1server_socket.close()
服务器这边主要是接收到图片字节数据,将图片写到后缀为.png的文件中。
程序结果如下:
image3是接收到的图片,dh是被传输的原图。QtTcpServer是用Qt写的服务器接收图片程序,下次再分享给大家。
如果需要完整程序,可在公众号后台留言。