Python 3:通过套接字发送文件。 (客户端-服务器程序)

时间:2018-07-25 06:57:33

标签: python python-3.x sockets

我遇到上述问题。假定客户端要求输入文件名并将文件名发送到服务器,然后服务器将打开该文件并显示它。问题是服务器没有打开文件并显示它。

下面是客户端。

#!/usr/bin/env python3 
import socket, os.path, datetime, sys

def Main():
    host = '127.0.0.1'
    port = 50001

    s = socket.socket()
    s.connect((host, port))

    Filename = input("Type in ur file ")
    s.send(Filename.encode('utf-8'))
    data = s.recv(1024).decode('utf-8')
    s.close()

if __name__ == '__main__':
    Main()

下面是服务器

#!/usr/bin/env python3

import socket
import os
import sys



def Main():
    host = '127.0.0.1'
    port = 50001

    s = socket.socket()
    s.bind((host,port))
    print("server Started")
    s.listen(1)
    c, addr = s.accept()
    print("Connection from: " + str(addr))
    while True:
        data = c.recv(1024).decode('utf-8')
        myfile = open(data, "r")
        if not data:
            break
        print("from connected user: " + myfile)

    c.close()

if __name__ == '__main__':
    Main()

1 个答案:

答案 0 :(得分:2)

我对您运行它的代码进行了一些最小的调整,以使server.py不断侦听给定的端口并发送回数据,每次调用client.py都会请求该数据。

server.py

#!/usr/bin/env python3
import socket
import os
import sys

def Main():
    host = '127.0.0.1'
    port = 50001

    s = socket.socket()
    s.bind((host,port))
    print("server Started")
    s.listen(1)
    while True:
        c, addr = s.accept()
        print("Connection from: " + str(addr))
        filename = ''
        while True:
            data = c.recv(1024).decode('utf-8')
            if not data:
                break
            filename += data
        print("from connected user: " + filename)
        myfile = open(filename, "rb")
        c.send(myfile.read())
        c.close()

if __name__ == '__main__':
    Main()

client.py

#!/usr/bin/env python3 
import socket, os.path, datetime, sys

def Main():
    host = '127.0.0.1'
    port = 50001

    s = socket.socket()
    s.connect((host, port))

    Filename = input("Type in ur file ")
    s.send(Filename.encode('utf-8'))
    s.shutdown(socket.SHUT_WR)
    data = s.recv(1024).decode('utf-8')
    print(data)
    s.close()

if __name__ == '__main__':
    Main()

现在有一些解释。

在服务器端。外循环接受一个连接,然后从该连接读取直到完成(稍后对此进行更多介绍)。打印调试信息,但请注意,您尝试print而不是文件名str(尝试连接时会失败)。我还以二进制模式打开文件(这样,我可以跳过bytes-> print的翻译。

在客户端。发送文件后,我已添加了关闭套接字的写入端的功能。请注意,在这种情况下,您可能需要使用sendall而不是send:请查看这些文档链接以获取详细信息。并且我为传入的数据添加了sendall

现在可以关闭客户端的写入端和内部循环读取(并且还与EOF提示有关。哪一个BTW在服务器端也适用,否则您应该循环执行)可能会看到您的内容被截断;另一个选择是也有发送循环。)流套接字将确保您顺序发送字节。就其本身而言,您不知道您的消息是否完整,也无法保证发送和接收数据的数量和大小(重新)。

服务器的内部循环一直在读取,直到我们看到socket(在python recv中我们收到了零长度的字符串)。当远程套接字(或至少它的写入端)已关闭时,会发生这种情况(由<script> function openProductTab(evt, tabName) { var i, tabcontent, openProductTab; tabcontent = document.getElementsByClassName("tabcontent"); for (i = 0; i < tabcontent.length; i++) { tabcontent[i].style.display = "none"; } tabProductLinks = document.getElementsByClassName("tabProductLinks"); for (i = 0; i < tabProductLinks.length; i++) { tabProductLinks[i].className = tabProductLinks[i].className.replace(" active", ""); } document.getElementById(tabName).style.display = "block"; evt.currentTarget.className += " active"; } // Get the element with id="defaultOpen" and click on it document.getElementById("defaultOpen").click(); </script>返回。由于我们仍然想重用连接,因此我们仅在客户端的发送端执行此操作。希望这可以帮助您前进。