Python 运行服务器的远程代码似乎没有响应?

Python 运行服务器的远程代码似乎没有响应?,python,sockets,Python,Sockets,我在一个服务器上工作,该服务器可以运行带有套接字的python代码,但我编写的代码似乎没有从客户端或服务器端响应。我仍然无法理解,当我运行我的server.py并连接到服务器时,服务器或客户端似乎没有输出。我也没有收到错误,只是没有工作/没有输出 Server.py: import socket port = 7142 s = socket.socket() host = socket.gethostname() s.bind((host, port)) s.listen(10) def

我在一个服务器上工作,该服务器可以运行带有套接字的python代码,但我编写的代码似乎没有从客户端或服务器端响应。我仍然无法理解,当我运行我的
server.py
并连接到服务器时,服务器或客户端似乎没有输出。我也没有收到错误,只是没有工作/没有输出

Server.py:

import socket 

port = 7142
s = socket.socket()
host = socket.gethostname()
s.bind((host, port))
s.listen(10)

def get_file():
    print ('Server listening....')
    while True:
        get_file.conn, addr = s.accept()
        print('Connection from', addr)
        get_file.data,file = get_file.conn.recv(1024)
        
        
        with open('received_file.txt', 'wb') as f:
            if not get_file.data:
                get_file.conn.send(b'There is no data sent between servers')
            f.write(get_file.data)


def compile_file():
    try:
        f = open('received_file.txt', 'r')
        code_str = f.read()
        code = compile(code_str, '', 'exec')
        return(exec(code).decode())
        
    except Exception as error:
        return(error.decode())

get_file()
conn = get_file.conn
compile_f = compile_file()
conn.send(compile_f)
conn.close()
Client.py

import socket
import time


s = socket.socket()
host = socket.gethostname()
port = 7142
file_name = 'file.txt'

s.connect((host, port))

data = s.recv(1024)
f = open(file_name,'rb')
l = f.read(1024)

while(l):
    s.send(l)
    break


print(repr(data))
time.sleep(10)
s.close()
f.close()
print('connection closed')
time.sleep(7)

服务器和客户端都在执行接收操作,因此都在等待对方发送一些数据。两个进程都被阻止

首先要做的是删除客户机中的初始
recv()
,以便它可以开始将文件内容发送到服务器

一旦修复,您将需要修改客户端读取和发送文件的方式。当前,该文件只读取一次,但您需要在while循环中读取要发送给客户端的下一个块。你可以这样重写它:

with open(file_name, 'rb') as f:
    while(True):
        l = f.read(1024)
        if not l:
            break
        s.send(l)
或者您可以使用“walrus”操作符
:=
来简化数据读取和文件结尾测试:

with open(file_name, 'rb') as f:
    while l := f.read(1024):
        s.send(l)
除此之外,客户端还必须为服务器提供一种方法,以确定它何时接收到所有文件。这可以通过两种方式实现:

  • 客户机在消息开始时发送消息的长度,以便服务器可以判断何时已收到所有消息,或者
  • 客户端可以在消息的末尾附加一个sentinel字符。服务器查找此字符并使用它确定消息的结尾
下面是在消息之后发送哨兵字符的代码。哨兵不得出现在数据中;EOT(ASCII 0x04)应该是安全的:

with open(file_name, 'rb') as f:
    while l := f.read(1024):
        s.send(l)
    s.send(b'\x04')     # EOT sentinel character
现在看看服务器,这是不正确的:

    get_file.data,file = get_file.conn.recv(1024)
因为
recv()
返回的是字节字符串,而不是元组。改为:

    conn, addr = s.accept()
    print('Connection from', addr)
    data = conn.recv(1024)
请注意,我已经删除了
get\u文件。
局部变量名称的前缀,因为没有理由将这些变量绑定到
get\u文件
函数对象。实际上,您应该接受此函数之外的连接,并将连接对象传递给函数。见下文

您需要向服务器添加一个循环来接收来自客户端的所有数据。与客户端类似,您可以执行以下操作:

def get_file(conn):
    with open('received_file.txt', 'wb') as f:
        while data := conn.recv(1024):
            if data[-1] == EOT:
                f.write(data[:-1])
                break
            f.write(data)
请注意,这段代码如何检查sentinel EOT字符的存在,以确定何时收到完整消息

并动议:

    print ('Server listening....')
    conn, addr = s.accept()
    print('Connection from', addr)
进入脚本的主体


以下是您的代码的完整版本以及上述更正:

server.py

import socket

port = 7142
s = socket.socket()
host = socket.gethostname()
s.bind((host, port))
s.listen(10)

EOT = ord(b'\x04')

def get_file(conn):
    with open('received_file.txt', 'wb') as f:
        while data := conn.recv(1024):
            if data[-1] == EOT:
                f.write(data[:-1])
                break
            f.write(data)

def compile_file():
    try:
        f = open('received_file.txt', 'r')
        code_str = f.read()
        code = compile(code_str, '', 'exec')
        return(exec(code).decode())

    except Exception as error:
        return(error.decode())

print('Server listening....')
conn, addr = s.accept()
print('Connection from', addr)

get_file(conn)
compile_f = compile_file()
print("replying to client")
conn.send(compile_f)
print('done')
conn.close()
s.close()
import socket
import time   

s = socket.socket()
host = socket.gethostname()
port = 7142
file_name = 'file.txt'

s.connect((host, port))

with open(file_name, 'rb') as f:
    while l := f.read(1024):
        s.send(l)
    s.send(b'\x04')     # EOT sentinel character

print("Sent request, waiting for reply...")
data = s.recv(1024)
print(repr(data))
time.sleep(10)
s.close()
f.close()
print('connection closed')
time.sleep(7)
client.py

import socket

port = 7142
s = socket.socket()
host = socket.gethostname()
s.bind((host, port))
s.listen(10)

EOT = ord(b'\x04')

def get_file(conn):
    with open('received_file.txt', 'wb') as f:
        while data := conn.recv(1024):
            if data[-1] == EOT:
                f.write(data[:-1])
                break
            f.write(data)

def compile_file():
    try:
        f = open('received_file.txt', 'r')
        code_str = f.read()
        code = compile(code_str, '', 'exec')
        return(exec(code).decode())

    except Exception as error:
        return(error.decode())

print('Server listening....')
conn, addr = s.accept()
print('Connection from', addr)

get_file(conn)
compile_f = compile_file()
print("replying to client")
conn.send(compile_f)
print('done')
conn.close()
s.close()
import socket
import time   

s = socket.socket()
host = socket.gethostname()
port = 7142
file_name = 'file.txt'

s.connect((host, port))

with open(file_name, 'rb') as f:
    while l := f.read(1024):
        s.send(l)
    s.send(b'\x04')     # EOT sentinel character

print("Sent request, waiting for reply...")
data = s.recv(1024)
print(repr(data))
time.sleep(10)
s.close()
f.close()
print('connection closed')
time.sleep(7)

谢谢你的awnser,但似乎还没有worked@PyCoder64:是的,还有一些问题需要处理,即服务器如何告知客户端已从文件发送了所有数据?由于客户端需要回复,因此它必须保持与服务器的连接打开,因此服务器不能使用关闭的套接字来告知客户端已完成发送。客户端可以发送文件长度作为请求的第一部分,也可以在最后发送sentinel值。服务器只是等待一个文件并复制它,然后在文件中运行python代码@PyCoder64:它不像你说的那么简单。服务器必须知道何时从客户端接收到所有数据。它不能这样做,除非它知道数据的长度,或者以其他方式得到通知,例如通过数据中没有出现的哨兵值。我会尽快更新我的答案。好的,谢谢你让我知道