【问题标题】:Send a file through sockets in Python在 Python 中通过套接字发送文件
【发布时间】:2012-03-12 00:40:37
【问题描述】:

我正在尝试用 python 编写一个实现套接字的程序。每个客户端发送一个 PDF 文件,服务器接收它,标题更改为“file_(number).pdf”(例如:file_1.pdf)。出现的问题是只有客户端才能成功发送文件。当第二个客户端尝试发送文件时,程序崩溃。我做错了什么,如何解决我的代码以允许 N 个客户端(N

这是服务器代码:

import socket
import sys
s = socket.socket()
s.bind(("localhost",9999))
s.listen(10) # Accepts up to 10 incoming connections..
sc, address = s.accept()

print address
i=1
f = open('file_'+ str(i)+".pdf",'wb') # Open in binary
i=i+1
while (True):

    # We receive and write to the file.
    l = sc.recv(1024)
    while (l):
        f.write(l)
        l = sc.recv(1024)
f.close()

sc.close()
s.close()

这是客户端代码:

import socket
import sys

s = socket.socket()
s.connect(("localhost",9999))
f = open ("libroR.pdf", "rb")
l = f.read(1024)
while (l):
    s.send(l)
    l = f.read(1024)
s.close()

为了简化我的代码,我总是使用文件名为“libroR.pdf”的书,但在完整代码中它是由 GUI 选择的。

【问题讨论】:

  • 向我们显示错误,并告诉我们受影响的是客户端还是服务器。
  • @Marcin 没有教我任何错误,只是第一个客户端发送文件并成功结束,服务器继续等待更多请求,当第二个客户端尝试连接时,客户端程序什么也不做并保持待机状态。

标签: python sockets


【解决方案1】:

您必须将所有从sc, address = s.accept()sc.close() 的代码放入另一个循环中,否则服务器会在收到第一个文件后直接终止。它没有崩溃,脚本刚刚完成。

[编辑]这是修改后的代码:

import socket
import sys
s = socket.socket()
s.bind(("localhost",9999))
s.listen(10) # Accepts up to 10 connections.

while True:
    sc, address = s.accept()

    print address
    i=1
    f = open('file_'+ str(i)+".pdf",'wb') #open in binary
    i=i+1
    while (True):       
    # receive data and write it to file
        l = sc.recv(1024)
        while (l):
                f.write(l)
                l = sc.recv(1024)
    f.close()


    sc.close()

s.close()

请注意,s.listen(10) 表示“set maximum accept rate to 10 connections”,而不是“在 10 个连接后停止”。

【讨论】:

  • 除了套接字读取循环之外的另一个循环?我没有明确的想法
  • 实际上 s.listen(10) 的意思是“允许多达 10 个未接受 () 的传入 TCP 连接同时被 TCP 堆栈排队”。如果 10 个传入的 TCP 连接已经在该套接字的 TCP 堆栈队列中,则任何其他的都将被拒绝(直到程序通过接受()处理队列中的一些连接)
【解决方案2】:

您的代码卡在第二个 while 循环中。

见:

import socket
import sys
s = socket.socket()
s.bind(("localhost",9999))
s.listen(10)

i=1

while True:
    sc, address = s.accept()

    print address

    f = open('file_'+str(i)+".pdf",'wb') #open in binary
    i=i+1
    print(i)
    l = 1
    while(l):
        l = sc.recv(1024)
        while (l):
            f.write(l)
            l = sc.recv(1024)
        f.close()


    sc.close()

s.close()

【讨论】:

    【解决方案3】:

    服务器:

    import socket
    from threading import Thread
    
    TCP_IP = 'localhost'
    TCP_PORT = 9001
    BUFFER_SIZE = 1024
    
    
    class ClientThread(Thread):
    
        def __init__(self, ip, port, sock):
            Thread.__init__(self)
            self.ip = ip
            self.port = port
            self.sock = sock
            print(" New thread started for "+ip+":"+str(port))
    
        def run(self):
            filename = 'anon234.jpeg'
            f = open(filename, 'rb')
            while True:
                l = f.read(BUFFER_SIZE)
                while (l):
                    self.sock.send(l)
                    #print('Sent ',repr(l))
                    l = f.read(BUFFER_SIZE)
                if not l:
                    f.close()
                    self.sock.close()
                    break
    
    
    tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    tcpsock.bind((TCP_IP, TCP_PORT))
    threads = []
    
    while True:
        tcpsock.listen(5)
        print("Waiting for incoming connections...")
        (conn, (ip, port)) = tcpsock.accept()
        print('Got connection from ', (ip, port))
        newthread = ClientThread(ip, port, conn)
        newthread.start()
        threads.append(newthread)
    
    for t in threads:
        t.join()
    

    客户:

    import socket
    import time
    
    TCP_IP = 'localhost'
    TCP_PORT = 9001
    BUFFER_SIZE = 1024
    
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((TCP_IP, TCP_PORT))
    recived_f = 'imgt_thread'+str(time.time()).split('.')[0]+'.jpeg'
    with open(recived_f, 'wb') as f:
        print('file opened')
        while True:
            #print('receiving data...')
            data = s.recv(BUFFER_SIZE)
            print('data=%s', (data))
            if not data:
                f.close()
                print('file close()')
                break
            # write data to a file
            f.write(data)
    
    print('Successfully get the file')
    s.close()
    print('connection closed')
    

    【讨论】:

      【解决方案4】:

      在处理第一个客户端连接后,您将关闭服务器套接字(代码中的s)。因此,您的服务器只处理一个客户端。围绕accept 循环并从sc 读取。

      【讨论】:

        【解决方案5】:

        使用此代码,您可以使用同一个 client.py 多次发送文件

        Server.py

        import socket
        import sys
        s = socket.socket()
        s.bind(("localhost",9999))
        s.listen(10) # Acepta hasta 10 conexiones entrantes.
        
        i = 1
        while True:
            sc, address = s.accept()
        
            print address
            f = open('file_'+ str(i)+".wav",'wb') #open in binary
            i=i+1
            while (True):
                # recibimos y escribimos en el fichero
                l = sc.recv(1024)
                f.write(l)
        
                if not l:
                    break
        
            f.close()
            sc.close()
            print('copied the file.')
        
        s.close()
        

        【讨论】:

          猜你喜欢
          • 2015-08-28
          • 2021-07-06
          • 1970-01-01
          • 2019-08-12
          • 2015-07-10
          • 2015-01-30
          • 1970-01-01
          • 1970-01-01
          • 2011-02-24
          相关资源
          最近更新 更多