2013-04-04 105 views
1

我正在使用python腳本將使用攝像頭拍攝的圖像發送到使用套接字的c#webserver的項目。我目前在Python客戶端使用類似的代碼串發送到服務器:使用python通過TCP發送圖像到c#服務器

info = bytearray("Text to send", "UTF-8") 
socket.send(info) 

將數據發送到C#的服務器,它的文本和數字功能完美。當試圖將從.bmp讀取的數據編碼爲「UTF-8」時遇到了一個問題,因爲嘗試返回不能將某些字符編碼爲UTF-8的錯誤。

我想知道是否有人對c#能夠識別的這種編碼方式有任何想法,或者如果有更好的方法來實現這個過程,我全都是耳朵。

我已經想出了幾個選項 - 1 - 使用類似谷歌驅動器來保存圖像,或FTP服務器,然後讓C#服務器從那裏檢索它或2 - 創建一個數據包系統包含RGB值並從服務器上的像素值重新創建圖像。

感謝您的幫助。

編輯:我曾嘗試將文件發送這樣

data = bytearray("123456789","UTF-8") 
file = open("image.bmp", "rb") 
data += file.read() 
socket.send(data) 

,並能夠成功retreive字符串「123456789」,但在此之後的數據是垃圾。我還實現了在發送數據前發送文件的大小,並且可以很好地檢索大小數字,但img數據保存爲黑色bmp。

編輯2:

這裏是我使用的嘗試和使用內存流重建圖像服務器和客戶端的代碼。我的客戶端代碼使用hcalves提到的過程。

客戶

if __name__ == "__main__": 
sock = socket.socket() 
sock.connect(("localhost", 50839)) 

with open("image.bmp", "rb") as fd: 
    buf = fd.read(1024) 
    while (buf): 
     sock.send(buf) 
     buf = fd.read(1024) 
sock.close() 

服務器

Socket client = server.AcceptSocket(); 
NetworkStream stream = new NetworkStream(client); 
byte[] imgData = new byte[1024]; 
MemoryStream memstream = new MemoryStream(); 
stream.Read(imgData,0, 1024); 
int counter = 0; 
while (stream.DataAvailable) 
{ 
    memstream.Write(imgData, 0, 1024); 
    stream.Read(imgData, 0, 1024); 
    counter = counter + 1024; 
} 

memstream.Seek(0, SeekOrigin.Begin); 

using (Stream file = File.OpenWrite("img.bmp")) 
{ 
    byte[] buffer = new byte[8*1024]; 
    int len; 
    while ((len = memstream.Read(buffer, 0, buffer.Length)) > 0) 
    { 
     file.Write(buffer,0,len); 
    } 
} 
+5

你爲什麼試圖將二進制圖像編碼成文本格式?獲取表示圖像數據的字節陣列,然後發送THAT數組。 – EricLaw 2013-04-04 19:09:31

+1

如果出於某種原因,您有反對僅僅發送原始字節的內容,您可以對其進行64位編碼。我不確定你會從中得到什麼,它會減慢運輸的速度。 – 2013-04-04 19:10:56

+0

c#圖像類能夠將base64字節數組解釋爲圖像嗎? – Chris 2013-04-04 19:13:29

回答

1

你不應該需要比這更多的食譜:

import socket 

if __name__ == "__main__": 
    sock = socket.socket() 
    sock.connect(("localhost", 50839)) 

    with open("data.bin", "rb") as fd: 
     buf = fd.read(1024) 
     while (buf): 
      sock.send(buf) 
      buf = fd.read(1024) 
    sock.close() 

出於實際的原因,你可以把strØ bjects(fd.read的結果)作爲原始數據,您不需要任何進一步的瘋狂編碼。只需迭代文件並通過套接字發送即可。測試運行該服務器剛剛呼應與python server.py > data2.bin到stdout:

import socket 
import sys 

if __name__ == "__main__": 
    sock = socket.socket() 
    sock.bind(("localhost", 50839)) 
    sock.listen(1) 

    client, address = sock.accept() 

    buf = client.recv(1024) 
    while (buf): 
     sys.stdout.write(buf) 
     buf = client.recv(1024) 

    client.close() 
    sock.close() 

校驗列出了二進制數據被正確傳送:

% md5 data.bin data2.bin  
MD5 (data.bin) = 8b3280072275badf3e53a6f7aae0b8be 
MD5 (data2.bin) = 8b3280072275badf3e53a6f7aae0b8be 

你的C#服務器應該能夠爲的就是接受這個數據。如果它不起作用,那是因爲你的服務器特別期待某些東西,而不僅僅是原始數據。

+0

我正在嘗試發送數據的方法,我必須在發送數據之前發送一個數字,但是我只是爲了獲取此數據而將這部分數據發送出去。我有c#服務器,在接收下一組1024字節之前將圖像數據存儲到存儲器流中。但是我仍然在圖像類中出現格式錯誤,這是我尋找編碼數據的不同方式的全部原因。 – Chris 2013-04-04 20:36:17

+0

無法訪問服務器代碼就無法獲得答案。它可以期待任何事情。 – hcalves 2013-04-04 20:43:40

+0

我更新了原始問題以包含服務器代碼 – Chris 2013-04-04 21:26:55