簡體   English   中英

用於傳輸照片的python套接字編程

[英]python socket programming for transferring a photo

我是python套接字編程的新手。 這是在Mininet主機中打開TCP套接字並將照片從一台主機發送到另一台主機的示例。 實際上,為了滿足我的要求,我更改了用於向另一台主機發送簡單消息( 將接收到的數據寫入文本文件 )的代碼。 盡管當我實現此修訂的代碼時,沒有錯誤,並且似乎可以正確傳輸,但是我不確定這是否是進行此傳輸的正確方法。 由於我在同一台計算機上運行兩個主機,因此我認為這可能會對結果產生影響。 我想請您檢查這是否是正確的轉移方式,還是應該添加或刪除某些內容。

mininetSocketTest.py#!/ usr / bin / python

from mininet.topo import Topo, SingleSwitchTopo
from mininet.net import Mininet
from mininet.log import lg, info
from mininet.cli import CLI

def main():
    lg.setLogLevel('info')

    net = Mininet(SingleSwitchTopo(k=2))
    net.start()

    h1 = net.get('h1')
    p1 = h1.popen('python myClient2.py')

    h2 = net.get('h2')
    h2.cmd('python myServer2.py')

    CLI( net )
    #p1.terminate()
    net.stop()

if __name__ == '__main__':
     main()

myServer2.py

import socket
import sys

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('10.0.0.1', 12345))

buf = 1024
f = open("2.jpg",'wb')

s.listen(1)
conn , addr = s.accept()
while 1:
    data = conn.recv(buf)
    print(data[:10])
    #print "PACKAGE RECEIVED..."
    f.write(data)   
    if not data: break
    #conn.send(data)
conn.close()
s.close()

myClient2.py:

import socket
import sys

f=open ("1.jpg", "rb")
print sys.getsizeof(f)
buf = 1024
data = f.read(buf)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('10.0.0.1',12345))


while (data):
    if(s.sendall(data)):
        #print "sending ..."
        data = f.read(buf)
        print(f.tell(), data[:10])
    else:
         s.close()
s.close()

client2此循環是錯誤的:

while (data):
    if(s.send(data)):
        print "sending ..."
        data = f.read(buf)

正如send文檔所說:

返回發送的字節數。 應用程序負責檢查所有數據是否已發送; 如果僅傳輸了一些數據,則應用程序需要嘗試傳送其余數據。 有關此主題的更多信息,請參考Socket Programming HOWTO

您甚至都沒有嘗試這樣做。 因此,盡管它可能可以在localhost上運行,但在輕載的機器上且文件很小,但是一旦您嘗試將其真正使用,它就會崩潰。

正如幫助所述,您需要做一些事情來交付其余的緩沖區。 由於可能沒有充分的理由,您不能僅在全部發送sendall ,因此最簡單的方法是調用sendall

與send()不同,此方法繼續從字節發送數據,直到所有數據都已發送或發生錯誤為止。 成功不返回任何內容。 如果出錯,則會引發異常…


這帶來了下一個問題:您不在任何地方進行任何異常處理。 也許還可以,但通常不行。 例如,如果您的一個套接字發生故障,而另一個套接字仍然發生故障,您是否要中止整個程序並硬斷開連接,還是想先完成所有發送的操作?

您至少應該使用一個finallywith子句,以確保您干凈地close套接字,以便另一端會得到一個不錯的EOF而不是異常。


另外,您的服務器代碼僅服務於一個客戶端,然后退出。 那真的是您想要的嗎? 通常,即使您不需要並發客戶端,您至少也要一遍一遍地接受和服務它們。


最后,服務器幾乎總是想這樣做:

s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

如果不這樣做,如果您嘗試在服務器完成后幾秒鍾內再次運行服務器(特定於平台的秒數,甚​​至可能取決於它是否以異常而不是完全關閉而完成),則bind將失敗,就像您試圖綁定另一個程序實際上正在使用的套接字一樣。

首先,您應該使用TCP而不是UDP。 TCP將確保您的客戶端/服務器正確接收了整個照片。 UDP更用於內容流。 絕對不是您的用例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM