简体   繁体   English

在 Python 中通过套接字发送文件

[英]Send a file through sockets in Python

I'm trying to make a program in python that implements sockets.我正在尝试用 python 制作一个实现套接字的程序。 Each client sends a PDF file and the server receives it and the title is changed to "file_(number).pdf" (eg: file_1.pdf).每个客户端发送一个PDF文件,服务器接收它,标题变为“file_(number).pdf”(例如:file_1.pdf)。 The problem presented is that only a client can send a file successfully.出现的问题是只有客户端才能成功发送文件。 When a second client tries to send the file, the program crashes.当第二个客户端尝试发送文件时,程序崩溃。 What am I doing wrong and how can I solve my code to allow N clients (with N < 20) to connect to the server and transfer files?我做错了什么,如何解决我的代码以允许 N 个客户端(N < 20)连接到服务器并传输文件?

Here's the server code:这是服务器代码:

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()

Here's the client code:这是客户端代码:

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()

To simplify my code, I always use a book with file name "libroR.pdf", but in the full code it is chosen by a GUI.为了简化我的代码,我总是使用文件名为“libroR.pdf”的书,但在完整代码中,它是由 GUI 选择的。

You must put all the code from sc, address = s.accept() upto sc.close() into another loop or the server simply terminates after receiving the first file.您必须将sc, address = s.accept()sc.close()所有代码放入另一个循环中,否则服务器在接收到第一个文件后就会终止。 It doesn't crash, the script is just finished.它没有崩溃,脚本刚刚完成。

[EDIT] Here is the revised code: [编辑]这是修改后的代码:

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()

Note that s.listen(10) means " set maximum accept rate to 10 connections ", not "stop after 10 connections".请注意, s.listen(10)表示“ 将最大接受率设置为 10 个连接”,而不是“在 10 个连接后停止”。

Your code is getting stuck in the second while loop.您的代码卡在第二个 while 循环中。

See:看:

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()

Server:服务器:

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()

Client:客户:

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')

You are closing the server socket ( s in your code) after handling the first client connection.在处理第一个客户端连接后,您正在关闭服务器套接字(代码中的s )。 Thus only one client is ever handled by your server.因此,您的服务器只处理一个客户端。 Make a loop around accept and reading from the sc .围绕accept和读取sc进行循环。

Using this code you can send files multiple time using the same client.py使用此代码,您可以使用同一个 client.py 多次发送文件

Server.py服务器.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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM