python實現(xiàn)同一局域網(wǎng)下傳輸圖片
簡述
Python可以通過網(wǎng)絡(luò)套接字來進(jìn)行傳輸圖片
這點(diǎn)還是比較有意思的。
下面用TCP來進(jìn)行實現(xiàn),適用于Python3
代碼功能簡述
下面代碼
- 實現(xiàn)了在一個電腦上發(fā)送圖片(Sender)
- 實現(xiàn)了在另外一個電腦(也可以是同一個電腦上的不同端口)接受圖片(Reciever)
- 只發(fā)一次,然后只收一次
- 新圖片會在舊圖片上多一個 “new_”前綴
- 必須要先開接受者代碼才行,之后再啟動發(fā)送者代碼(不然發(fā)送者代碼會直接被拒絕)
- 下面是固定了在一個電腦上(看ip地址,下面寫的是127.0.0.1,如果是其他電腦就寫其他電腦上的ip地址)
- 另外本程序只能在同一個局域網(wǎng)下使用(就算是廣域網(wǎng)上,那就必須要使用廣域網(wǎng)的ip地址)
代碼
【后附解析】
Sender.py (發(fā)送者)
import socket
import os
import sys
import struct
def sock_client():
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', 6666))
except socket.error as msg:
print(msg)
print(sys.exit(1))
while True:
filepath = input('input the file: ')
# filepath = 'test.png'
fhead = struct.pack(b'128sl', bytes(os.path.basename(filepath), encoding='utf-8'), os.stat(filepath).st_size)
s.send(fhead)
print('client filepath: {0}'.format(filepath))
fp = open(filepath, 'rb')
while 1:
data = fp.read(1024)
if not data:
print('{0} file send over...'.format(filepath))
break
s.send(data)
s.close()
break
if __name__ == '__main__':
sock_client()
Reciever.py (接受者)
import socket
import os
import sys
import struct
def socket_service():
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', 6666))
s.listen(10)
except socket.error as msg:
print(msg)
sys.exit(1)
print("Wait")
while True:
sock, addr = s.accept()
deal_data(sock, addr)
break
s.close()
def deal_data(sock, addr):
print("Accept connection from {0}".format(addr))
while True:
fileinfo_size = struct.calcsize('128sl')
buf = sock.recv(fileinfo_size)
if buf:
filename, filesize = struct.unpack('128sl', 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()
解析:
發(fā)送者代碼:
還是先創(chuàng)建TCP套接字,并發(fā)起連接:
具體代碼如下:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', 6666))
except socket.error as msg:
print(msg)
print(sys.exit(1))
接下來的While循環(huán)中,就開始進(jìn)行圖片發(fā)送
- 通過struct庫進(jìn)行打包,然后再用套接字來發(fā)送
- 注意:網(wǎng)絡(luò)上的有些代碼是不能直接用的,比如在這里,就需要把str變成bytes
- 通過os庫來獲取文件的基本名(這個是為了避免有些文件中包含具體路徑)
- 通過os庫來獲取文件的大小(通過文件狀態(tài)中關(guān)于大小的描述中獲取到)
fhead = struct.pack(b'128sl', bytes(os.path.basename(filepath), encoding='utf-8'), os.stat(filepath).st_size) s.send(fhead)
之后再通過二進(jìn)制方式來獲取文件。
然后再發(fā)送出去,每次發(fā)送固定長度的數(shù)據(jù)。先讀,再判斷是否為空,再發(fā)送。
接受端:
還是一樣,先創(chuàng)建套接字(不過這個需要綁定對應(yīng)的ip以及端口)
具體代碼如下:(這里寫的是監(jiān)聽10個套接字對象,但是在我們代碼中并沒喲用到)
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', 6666))
s.listen(10)
except socket.error as msg:
print(msg)
sys.exit(1)
之后就進(jìn)入到循環(huán),來判斷,是否獲取到sock對象,這里是會進(jìn)入阻塞狀態(tài)的。
在deal_data中就開始通過連接的對象來獲取數(shù)據(jù)。
一樣,還是一個無限循環(huán),但其實本質(zhì)上還是空的。。。沒什么特別的。
之后就是對于傳過來的文件名處理一下,這里的這些“128sl”,其實就是一個大小規(guī)模(類似于打包的箱子大小的樣子)。然后就是得到新的文件名了。
對應(yīng)的代碼如下:
filename, filesize = struct.unpack('128sl', buf)
fn = filename.decode().strip('\x00')
new_filename = os.path.join('./', 'new_' + fn)
之后的recvd_size,其實就是為了來計數(shù)的標(biāo)簽
之后就不斷地收,邊收邊寫入文件,一直到收完了之后。就關(guān)閉掉對應(yīng)的文件流
最后關(guān)閉套接字,退出循環(huán)
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Python實現(xiàn)PyPDF2處理PDF文件的方法示例
這篇文章主要介紹了Python實現(xiàn)PyPDF2處理PDF文件的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09
Python中為feedparser設(shè)置超時時間避免堵塞
為feedparser設(shè)置一個超時時間,可是feedparser并沒有提供這個功能,只好采用其他方法了,感興趣的朋友可以看看2014-09-09
解決import tensorflow as tf 出錯的原因
這篇文章主要介紹了解決import tensorflow as tf 出錯的原因,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
python可視化數(shù)據(jù)分析pyecharts初步嘗試
這篇文章主要為大家介紹了python可視化數(shù)據(jù)分析pyecharts初步嘗試,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04
Python中使用ConfigParser解析ini配置文件實例
這篇文章主要介紹了Python中使用ConfigParser解析ini配置文件實例,本文給出了創(chuàng)建和讀取ini文件的例子,需要的朋友可以參考下2014-08-08

