我正在從服務器捕獲螢屏截圖,然后將其發送到客戶端,但是影像全部作為一個大檔案發送到大小不斷擴大的客戶端。這只發生在我從一臺機器發送到另一臺機器時(我在本地網路上作業)但是當從我的機器上運行客戶端和服務器時它們作業正常。注意:對于另一臺機器上的客戶端,我使用pyinstaller打包成exe,因為這臺機器沒有python。
服務器代碼:
host="192.168.43.79" # Set the server address to variable host
port=4446 # Sets the variable port to 4446
import time
import pyautogui
from socket import *
import os
s=socket(AF_INET, SOCK_STREAM)
s.bind((host,port))
print("Listening for connections.. ")
q,addr=s.accept()
i = 0
while True:
screenshot = pyautogui.screenshot()
screenshot.save(str(i) ".jpg")
with open(str(i) ".jpg", "rb") as f:
data = f.read(4096)
while data:
q.send(data)
data = f.read(4096)
q.send(b"full")
i = 1
time.sleep(0.3)
客戶端代碼:
host="192.168.43.79" # Set the server address to variable host
port=4446 # Sets the variable port to 4446
from multiprocessing.reduction import recv_handle
from socket import * # Imports socket module
s=socket(AF_INET, SOCK_STREAM) # Creates a socket
s.connect((host,port))
i = 0
while True:
with open(str(i) "s.jpg", "wb") as f:
recv_data = s.recv(4096)
while recv_data:
f.write(recv_data)
recv_data = s.recv(4096)
if(recv_data == b"full"):
break
i = 1
uj5u.com熱心網友回復:
這里有各種錯誤的假設會導致您看到的問題。錯誤的假設是:
- 這
send(data)將寫入所有資料
它可能發送的更少。您需要檢查回傳值或使用sendall來確定。 - 發送者中的單個與接收者中
send的單個匹配TCP 只是一個非結構化位元組流。不添加訊息語意,因此單個可能導致多個,多個可能導致單個等。具體后跟可能是as ,因此缺少檢測影像結束的代碼。recvsendsendrecvsendrecvsend("data")send("full")recv(4096)"datafull"
至于為什么它在本地機器上作業而不是在遠程機器上作業 - 在后一種情況下,send組合在一起并recv作為一個整體的機會更高。
uj5u.com熱心網友回復:
正如 Steffen Ulrich 所說,您應該將sendall其用于發送和接收,我們創建了一個專門的函式my_recv,該函式將重復呼叫socket.recv,直到收到預期的位元組數。此外,在發送實際檔案資料之前,包含檔案長度的二進制表示的 4 位元組標頭(如果您的檔案大小允許,您可以使長度更大)。通過這種方式,客戶端確切地知道它應該為每個檔案接收多少資料。
服務器代碼
host="192.168.43.79" # Set the server address to variable host
port=4446 # Sets the variable port to 4446
import time
import pyautogui
from socket import *
import os
s=socket(AF_INET, SOCK_STREAM)
s.bind((host,port))
s.listen(1) # This should be called
print("Listening for connections.. ")
q,addr=s.accept()
i = 0
while True:
screenshot = pyautogui.screenshot()
screenshot.save(str(i) ".jpg")
with open(str(i) ".jpg", "rb") as f:
# Get length by positioning to end of file
image_length = f.seek(0, 2)
f.seek(0, 0) # Seek back to beginning of file
# Convert image length to a 4-byte array:
image_length_bytes = image_length.to_bytes(4, 'big')
q.sendall(image_length_bytes)
data = f.read(4096)
while len(data):
q.sendall(data)
data = f.read(4096)
i = 1
客戶代碼
host="192.168.43.79" # Set the server address to variable host
port=4446 # Sets the variable port to 4446
from multiprocessing.reduction import recv_handle
from socket import * # Imports socket module
s=socket(AF_INET, SOCK_STREAM) # Creates a socket
s.connect((host,port))
def my_recv(msg_length):
chunks = []
bytes_to_recv = msg_length
while bytes_to_recv:
chunk = s.recv(bytes_to_recv)
if chunk == b'':
raise RuntimeError("socket connection broken")
chunks.append(chunk)
bytes_to_recv -= len(chunk)
return b''.join(chunks)
i = 0
while True:
image_length_bytes = my_recv(4)
image_length = int.from_bytes(image_length_bytes, 'big')
with open(str(i) "s.jpg", "wb") as f:
bytes_to_recv = image_length
while bytes_to_recv:
recv_data = my_recv(min(4096, bytes_to_recv))
f.write(recv_data)
bytes_to_recv -= len(recv_data)
i = 1
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/505824.html
標籤:Python python-3.x 图片 插座 联网
