我正在尝试实现一个程序,该程序将使UDP服务器能够发送客户端请求的文件,并在特定目录中发送文件后对其进行日志记录。
任何人都可以指导我使用Code发送文件并在Python中记录它吗? 此外,我们需要以10 KB的块和最后的$发送数据,以宣布数据已完成。如果我尝试运行服务器端代码:这是我得到的错误:
任何帮助表示赞赏。提前致谢。
服务器端:
import socket
import threading
import os
def RetrFile(name, sock):
filename = sock.recv(1024)
if os.path.isfile(filename):
sock.send("EXISTS " + str(os.path.getsize(filename)))
userResponse = sock.recv(1024)
if userResponse[:2] == 'OK':
with open(filename, 'rb') as f:
bytesToSend = f.read(1024)
sock.send(bytesToSend)
while bytesToSend != "":
bytesToSend = f.read(1024)
sock.send(bytesToSend)
else:
sock.send("ERR ")
sock.close()
def Main():
host = '192.168.0.24'
port = 9090
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host,port))
s.listen(5)
print("Server Started.")
while True:
c, addr = s.accept()
print("client connedted ip:<" + str(addr) + ">")
t = threading.Thread(target=RetrFile, args=("RetrThread", c))
t.start()
s.close()
if __name__ == '__main__':
Main()
客户端:
import socket
def Main():
host = '192.168.0.24'
port = 9090
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect((host, port))
print("connected")
filename = raw_input("Filename? -> ")
if filename != 'q':
s.send(filename)
data = s.recv(1024)
if data[:6] == 'EXISTS':
filesize = long(data[6:])
message = raw_input("File exists, " + str(filesize) + "Bytes, download? (Y/N)? -> ")
if message == 'Y':
s.send("OK")
f = open('new_' + filename, 'wb')
data = s.recv(1024)
totalRecv = len(data)
f.write(data)
while totalRecv < filesize:
data = s.recv(1024)
totalRecv += len(data)
f.write(data)
print ("{0:.2f}".format((totalRecv / float(filesize)) * 100) + "% Done")
print("Download Complete!")
f.close()
else:
print ("File Does Not Exist!")
s.close()
if __name__ == '__main__':
Main()
答案 0 :(得分:2)
虽然您想使用UDP,但所使用的调用更符合基于TCP的通信。如果您只是更改客户端和服务器中的以下行,这将在TCP
上正常工作来自:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
到
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
在服务器和客户端。
对于基于UDP的通信,只需要bind和recv。对TCP进行调用是为了接受服务器端的连接。类似地,在客户端,不需要连接调用,如果要设置源端口,然后是sendto,则绑定。对于服务器端来说是这样的
Server.py
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host,port))
#s.listen(5)
print("Server Started.")
while True:
#c, addr = s.accept()
data, client_addr = s.recvfrom(1024)
另请注意,服务器需要知道发送给客户端的内容,因此在线程中,如果需要并发服务器,则需要维护每个client_addr的状态。另一种方法是使用TFTP样式方法,作为响应的一部分,您发送不同的端口号以联系基于UDP的服务器,以便主端口可以返回到接收更多请求。此外,所有发送呼叫都必须转为必须指定客户端地址的sendto呼叫。
同样在客户端,你需要的东西如下(我已经评论了下面的TCP风格部分)
host = '127.0.0.1'
port = 9090
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server = (host, port)
#s.connect((host, port))
#print("connected")
filename = raw_input("Filename? -> ")
if filename != 'q':
s.sendto(filename, server)
data,server = s.recvfrom(1024)
通过一些修改,我能够在我的系统上传输你的文件。