Python 螺纹套筒不';t使用sendall传输所有数据
我目前遇到一个问题,下面的代码只从套接字读取前1028个字节,然后挂起等待更多字节,即使其余的已经发送。我认为这可能是代码导致的问题,但它只发生在我从客户端接收数据到服务器时(这是多线程的)。当我反向运行代码(服务器向客户机发送数据)时,代码运行没有问题 这就是目前的失败之处: 客户端代码:Python 螺纹套筒不';t使用sendall传输所有数据,python,multithreading,sockets,tcp,Python,Multithreading,Sockets,Tcp,我目前遇到一个问题,下面的代码只从套接字读取前1028个字节,然后挂起等待更多字节,即使其余的已经发送。我认为这可能是代码导致的问题,但它只发生在我从客户端接收数据到服务器时(这是多线程的)。当我反向运行代码(服务器向客户机发送数据)时,代码运行没有问题 这就是目前的失败之处: 客户端代码: with open(commands[1], "rb") as file: data = file.read() # Sends the length of the file to t
with open(commands[1], "rb") as file:
data = file.read()
# Sends the length of the file to the server
serverSocket.sendall(str(len(data)).encode())
# Sends the data to the server
data = file.read(1024)
while data:
data = file.read(1024)
serverSocket.sendall(data)
# Gets the total length of the file
dataLen = int(clientsocket.recv(1024).decode())
totalData = ""
while len(totalData) < dataLen:
# Reads in and appends the data to the variable
data = clientsocket.recv(1024).decode()
totalData += data
以及服务器代码:
with open(commands[1], "rb") as file:
data = file.read()
# Sends the length of the file to the server
serverSocket.sendall(str(len(data)).encode())
# Sends the data to the server
data = file.read(1024)
while data:
data = file.read(1024)
serverSocket.sendall(data)
# Gets the total length of the file
dataLen = int(clientsocket.recv(1024).decode())
totalData = ""
while len(totalData) < dataLen:
# Reads in and appends the data to the variable
data = clientsocket.recv(1024).decode()
totalData += data
我改变了这一点,因为我认为recv可能会出现问题,无法从客户端获取所有数据包,但客户端认为所有数据包都已发送
最小可复制代码:
SERVER.PY
from socket import socket, AF_INET, SOCK_STREAM, error
from threading import Thread, Lock
from _thread import interrupt_main
import logging
from sys import stdout
from os import makedirs
from pathlib import Path
class Server:
def __init__(self, host, port):
logging.basicConfig(stream=stdout, level=logging.INFO, format='%(asctime)s - %(message)s')
self.host = host
self.port = port
self.quitVal = False
self.threads = []
self.lock = Lock()
self.sock = None
self.open()
def open(self):
sock = socket(AF_INET, SOCK_STREAM)
sock.bind((self.host, self.port))
sock.listen(5)
self.sock = sock
def listen(self):
try:
while self.quitVal != True:
(clientsocket, address) = self.sock.accept()
# This creates a threaded connection as this is the choke for the connection
thread = Thread(target=self.connection, args=(clientsocket, address), daemon=True)
self.threads.append(thread)
thread.start()
except OSError:
quit()
def connection(self, clientsocket, address):
while self.quitVal != True:
# We are going to allow multiple file transfers at one time on a connection
requestThreads = []
# The client innitially sends a command "s<command> [<fileLocation>]"
data = clientsocket.recv(4096).decode("utf-8")
data = data.split()
data[0] = data[0].lower()
if data[0] == "get":
thread = Thread(target=self.get, args=(clientsocket, data[1]), daemon=True)
requestThreads.append(thread)
thread.start()
elif data[0] == "put":
thread = Thread(target=self.put, args=(clientsocket, data[1]), daemon=True)
requestThreads.append(thread)
thread.start()
clientsocket.close()
def get(self, clientsocket, fileLocation):
# Tries to get the file, and sends it all to the client
with self.lock:
try:
with open(fileLocation, "rb") as file:
data = file.read()
# Sends the length of the file to the client
clientsocket.sendall(str(len(data)).encode())
# Byte to separate the input from length and file
response = self.sock.recv(1).decode()
# Sends the data to the client
clientsocket.sendall(data)
except IOError as e:
print("\nFile doesn't exist")
def put(self, clientsocket, fileLocation):
# Gets the total length of the file
with self.lock:
dataLen = int(clientsocket.recv(1024).decode())
totalData = ""
# Gets the total length of the file
dataLen = int(clientsocket.recv(1024).decode())
totalData = ""
# Byte to separate the input from length and file
clientsocket.sendall("0".encode())
while len(totalData) < dataLen:
# Reads in and appends the data to the variable
data = clientsocket.recv(2048).decode()
totalData += data
logging.info(totalData)
server = Server("127.0.0.1", 10002)
server.listen()
from socket import socket, AF_INET, SOCK_STREAM, error
from threading import Thread, Lock
from _thread import interrupt_main
import logging
from sys import stdout
from os import makedirs
from pathlib import Path
class Client:
def __init__(self, host, port):
self.host = host
self.port = port
self.quitVal = False
self.sock = self.open()
self.threads = []
self.lock = Lock()
def open(self):
try:
sock = socket(AF_INET, SOCK_STREAM)
sock.connect((self.host, self.port))
except error as err:
return None
return sock
def get(self, commands):
# Sends the request for the file to the server using the main Sock
with self.lock:
command = "GET " + commands[0]
self.sock.send(command.encode())
dataLen = int(self.sock.recv(1024).decode())
totalData = ""
self.sock.sendall("0".encode())
while len(totalData) < dataLen:
data = self.sock.recv(2048).decode()
totalData += data
def put(self, commands):
with self.lock:
# Sends the put call command to the server
command = "PUT " + commands[1]
self.sock.sendall(command.encode())
try:
with open(commands[1], "rb") as file:
data = file.read()
# Sends the length of the file to the server
self.sock.sendall(str(len(data)).encode())
# Byte to separate the input from length and file
response = self.sock.recv(1).decode()
# Sends the data to the server
self.sock.sendall(data)
except IOError as e:
logging.info("\nFile doesn't exist")
client = Client("127.0.0.1", 10002)
print("foo")
client.get(["foo.txt", "bar.txt"])
client.put(["foo.txt", "bar1.txt"])
从套接字导入套接字、AF\u INET、SOCK\u流,错误
从线程导入线程,锁定
从线程导入中断主线程
导入日志记录
从系统导入标准输出
从操作系统导入makedirs
从pathlib导入路径
类服务器:
定义初始化(自身、主机、端口):
logging.basicConfig(stream=stdout,level=logging.INFO,格式='%(asctime)s-%(message)s')
self.host=host
self.port=端口
self.quitVal=False
self.threads=[]
self.lock=lock()
self.sock=无
self.open()
def打开(自):
sock=套接字(AF\u INET,sock\u STREAM)
sock.bind((self.host,self.port))
短袜,听(5)
self.sock=sock
def监听(self):
尝试:
而self.quitVal!=正确:
(clientsocket,address)=self.sock.accept()
#这将创建一个螺纹连接,因为这是连接的扼流圈
thread=thread(target=self.connection,args=(clientsocket,地址),daemon=True)
self.threads.append(线程)
thread.start()
除操作错误外:
退出
def连接(self、clientsocket、地址):
而self.quitVal!=正确:
#我们将允许在一个连接上同时传输多个文件
requestThreads=[]
#客户端第一次发送命令“s[]”
数据=clientsocket.recv(4096).decode(“utf-8”)
data=data.split()
数据[0]=数据[0]。下限()
如果数据[0]=“获取”:
thread=thread(target=self.get,args=(clientsocket,数据[1]),daemon=True)
requestThreads.append(线程)
thread.start()
elif数据[0]=“put”:
thread=thread(target=self.put,args=(clientsocket,数据[1]),daemon=True)
requestThreads.append(线程)
thread.start()
clientsocket.close()
def get(self、clientsocket、fileLocation):
#尝试获取文件,并将其全部发送到客户端
使用self.lock:
尝试:
打开(文件位置,“rb”)作为文件:
data=file.read()
#将文件的长度发送到客户端
clientsocket.sendall(str(len(data)).encode())
#字节将输入与长度和文件分隔
response=self.sock.recv(1.decode())
#将数据发送到客户端
clientsocket.sendall(数据)
除IOE错误外:
打印(“\n文件不存在”)
def put(self、clientsocket、fileLocation):
#获取文件的总长度
使用self.lock:
dataLen=int(clientsocket.recv(1024.decode())
totalData=“”
#获取文件的总长度
dataLen=int(clientsocket.recv(1024.decode())
totalData=“”
#字节将输入与长度和文件分隔
clientsocket.sendall(“0.encode())
而len(totalData)
CLIENT.PY
from socket import socket, AF_INET, SOCK_STREAM, error
from threading import Thread, Lock
from _thread import interrupt_main
import logging
from sys import stdout
from os import makedirs
from pathlib import Path
class Server:
def __init__(self, host, port):
logging.basicConfig(stream=stdout, level=logging.INFO, format='%(asctime)s - %(message)s')
self.host = host
self.port = port
self.quitVal = False
self.threads = []
self.lock = Lock()
self.sock = None
self.open()
def open(self):
sock = socket(AF_INET, SOCK_STREAM)
sock.bind((self.host, self.port))
sock.listen(5)
self.sock = sock
def listen(self):
try:
while self.quitVal != True:
(clientsocket, address) = self.sock.accept()
# This creates a threaded connection as this is the choke for the connection
thread = Thread(target=self.connection, args=(clientsocket, address), daemon=True)
self.threads.append(thread)
thread.start()
except OSError:
quit()
def connection(self, clientsocket, address):
while self.quitVal != True:
# We are going to allow multiple file transfers at one time on a connection
requestThreads = []
# The client innitially sends a command "s<command> [<fileLocation>]"
data = clientsocket.recv(4096).decode("utf-8")
data = data.split()
data[0] = data[0].lower()
if data[0] == "get":
thread = Thread(target=self.get, args=(clientsocket, data[1]), daemon=True)
requestThreads.append(thread)
thread.start()
elif data[0] == "put":
thread = Thread(target=self.put, args=(clientsocket, data[1]), daemon=True)
requestThreads.append(thread)
thread.start()
clientsocket.close()
def get(self, clientsocket, fileLocation):
# Tries to get the file, and sends it all to the client
with self.lock:
try:
with open(fileLocation, "rb") as file:
data = file.read()
# Sends the length of the file to the client
clientsocket.sendall(str(len(data)).encode())
# Byte to separate the input from length and file
response = self.sock.recv(1).decode()
# Sends the data to the client
clientsocket.sendall(data)
except IOError as e:
print("\nFile doesn't exist")
def put(self, clientsocket, fileLocation):
# Gets the total length of the file
with self.lock:
dataLen = int(clientsocket.recv(1024).decode())
totalData = ""
# Gets the total length of the file
dataLen = int(clientsocket.recv(1024).decode())
totalData = ""
# Byte to separate the input from length and file
clientsocket.sendall("0".encode())
while len(totalData) < dataLen:
# Reads in and appends the data to the variable
data = clientsocket.recv(2048).decode()
totalData += data
logging.info(totalData)
server = Server("127.0.0.1", 10002)
server.listen()
from socket import socket, AF_INET, SOCK_STREAM, error
from threading import Thread, Lock
from _thread import interrupt_main
import logging
from sys import stdout
from os import makedirs
from pathlib import Path
class Client:
def __init__(self, host, port):
self.host = host
self.port = port
self.quitVal = False
self.sock = self.open()
self.threads = []
self.lock = Lock()
def open(self):
try:
sock = socket(AF_INET, SOCK_STREAM)
sock.connect((self.host, self.port))
except error as err:
return None
return sock
def get(self, commands):
# Sends the request for the file to the server using the main Sock
with self.lock:
command = "GET " + commands[0]
self.sock.send(command.encode())
dataLen = int(self.sock.recv(1024).decode())
totalData = ""
self.sock.sendall("0".encode())
while len(totalData) < dataLen:
data = self.sock.recv(2048).decode()
totalData += data
def put(self, commands):
with self.lock:
# Sends the put call command to the server
command = "PUT " + commands[1]
self.sock.sendall(command.encode())
try:
with open(commands[1], "rb") as file:
data = file.read()
# Sends the length of the file to the server
self.sock.sendall(str(len(data)).encode())
# Byte to separate the input from length and file
response = self.sock.recv(1).decode()
# Sends the data to the server
self.sock.sendall(data)
except IOError as e:
logging.info("\nFile doesn't exist")
client = Client("127.0.0.1", 10002)
print("foo")
client.get(["foo.txt", "bar.txt"])
client.put(["foo.txt", "bar1.txt"])
从套接字导入套接字、AF\u INET、SOCK\u流,错误
从线程导入线程,锁定
从线程导入中断主线程
导入日志记录
从系统导入标准输出
从操作系统导入makedirs
从pathlib导入路径
类客户端:
定义初始化(自身、主机、端口):
self.host=host
self.port=端口
self.quitVal=False
self.sock=self.open()
self.threads=[]
self.lock=lock()
def打开(自):
尝试:
sock=套接字(AF\u INET,sock\u STREAM)
sock.connect((self.host,self.port))
除错误作为错误外:
一无所获
回程短袜
def get(自我,命令):
#使用主Sock将文件请求发送到服务器
使用self.lock:
command=“GET”+命令[0]
self.sock.send(command.encode())
dataLen=int(self.sock.recv(1024.decode())
totalData=“”
self.sock.sendall(“0.encode())
而len(totalData)
请尝试为我们提供一个服务。否则,就无法知道它是如何与线程代码交互的