繁体   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