Python - [Errno 10054] An existing connection was forcibly closed by the remote host - sending pickled data issues
I managed to finally accomplish what I wanted to do in the first place. I wanted to write a send function that sent out X amount of pickled data alongside a receive function that received X amount of pickled data without throwing errors when it received data that was too small to be pickled.
See the send_data
and the receive_data
functions for the solution in network.py
. The server file server.py
requires these functions as well although slightly different. In your client file you should thus make use of the network.send_data
function to send data from the client to the server.
network.py
import socket
import pickle
HEADERSIZE = 10
class Network:
def __init__(self):
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server = "enter server address"
self.port = 5555
self.addr = (self.server, self.port)
self.p = self.connect()
def getP(self):
return self.p
def connect(self):
try:
self.client.connect(self.addr)
return self.client.recv(2048).decode()
except:
pass
# works but only sends and receives string encoded data without a buffer
def send1(self, data):
try:
self.client.send(str.encode(data))
return pickle.loads(self.client.recv(2048))
except socket.error as e:
print(e)
# works but only sends and receives pickled data without a buffer
def send2(self, data):
try:
self.client.send(pickle.dumps(data))
return pickle.loads(self.client.recv(2048))
except socket.error as e:
print(e)
# this is the function you should use, it uses a receive function that has a buffer
# and ensures that you receive ALL the information that you sent without throwing errors
def send_data(self, data):
data_to_send = pickle.dumps(data)
data_size = bytes(f'{len(data_to_send):<{10}}', "utf-8")
try:
self.client.send(data_size + data_to_send)
package = self.receive_data()
return package
except socket.error as e:
print(e)
def receive_data(self):
full_msg = b''
new_msg = True
while True:
msg = self.client.recv(16)
if new_msg:
msglen = int(msg[:HEADERSIZE])
new_msg = False
full_msg += msg
if len(full_msg)-HEADERSIZE == msglen:
data = pickle.loads(full_msg[HEADERSIZE:])
break
return data
server.py
import socket
import pickle
from _thread import *
import sys
from game import Game
server = "enter server address"
port = 5555
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.bind((server, port))
except socket.error as e:
print(e)
s.listen(2)
print("Waiting for a connection, Server Started")
connected = set()
games = {}
id_count = 0
HEADERSIZE = 10
def receive_data(sock):
full_msg = b''
new_msg = True
while True:
msg = sock.recv(16)
if new_msg:
msglen = int(msg[:HEADERSIZE])
new_msg = False
full_msg += msg
if len(full_msg)-HEADERSIZE == msglen:
data = pickle.loads(full_msg[HEADERSIZE:])
break
return data
def send_data(clientsocket, data):
data_to_send = pickle.dumps(data)
data_size = bytes(f'{len(data_to_send):<{10}}', "utf-8")
try:
clientsocket.send(data_size + data_to_send)
except socket.error as e:
print(e)
def threadedClient(conn, p, game_id):
global id_count
conn.send(str.encode(str(p)))
reply = ""
while True:
try:
data = receive_data(conn)
# check if the game still exists
if game_id in games:
game = games[game_id]
if not data:
break
else:
if data == "reset":
game.resetWent()
elif data != "get":
game.play(p, data)
reply = game
send_data(conn, reply)
else:
break
except Exception as e:
print("Failed try")
print(e)
break
print("Lost connection")
try:
print("Closing game", game_id)
del games[game_id]
except:
pass
id_count -=1
conn.close()
while True:
conn, addr = s.accept()
print("Connected to: ", addr)
id_count += 1
p = 0
game_id = (id_count - 1) // 2
if id_count % 2 == 1:
games[game_id] = Game(game_id)
print("Creating a new game...")
else:
games[game_id].ready = True
p = 1
start_new_thread(threadedClient, (conn, p, game_id))
How to handle urllib.error.URLError: <urlopen error [WinError 10054] An existing connection was forcibly closed by the remote host>?
For possible causes for this error, you could have a look at python: [Errno 10054] An existing connection was forcibly closed by the remote host. My conclusion after reading the highest vote answers is just that it can happen and your code should be prepared to it.
I would use a try: ... except ...
block in a loop here and and add a increasing delay before retrying a failed connection:
def download_file(url):
# prefere with when exceptions are expected
with open(url.split("=")[-1] + ".pdf", 'wb') as fp:
delay = 5
max_retries = 3
for _ in range(max_retries):
try:
req = urlopen(url)
CHUNK = 20480
chunk = req.read(CHUNK)
fp.write(chunk)
break # do not loop after a successfull download...
except urllib.error.URLError:
time.sleep(delay)
delay *= 2
else: # signal an abort if download was not possible
print(f"Failed for {url} after {max_retries} attempt")
# or if you want to abort the script
# raise Exception(f"Failed for {url} after {max_retries} attempt")
How to catch this Python exception: error: [Errno 10054] An existing connection was forcibly closed by the remote host
The error type is socket.error, the documentation is here.
Try modiffying your code like this:
import socket
import errno
try:
Deleting filename
self.ftp.delete(filename)
return True
except (error_reply, error_perm, error_temp):
return False
except socket.error as error:
if error.errno == errno.WSAECONNRESET:
reconnect()
retry_action()
else:
raise
Related Topics
Taking Data from Drop-Down Menu Using Flask
How to Make a Roll the Dice Command With My Discord Bot
Reduce Multi-Index/Multi-Level Dataframe to Single Index, Single Level
Selecting Specific Rows and Columns from Numpy Array
How to Add Parenthesis Around a Substring in a String
How to Compare 2 Indexes in Same List in Python
How-To Run Tensorflow on Multiple Core and Threads
How to Get Slope from Timeseries Data in Pandas
Calling a Function of a Module by Using Its Name (A String)
How to Reset Anaconda Root Environment
How to Run Two Python Scripts Simultaneously from a Master Script
How to Repeatedly Execute a Function Every X Seconds
Find the Index of the First Digit in a String
Finding the Max Value in a Two Dimensional Array
Possible to Loop Through Excel Files With Differently Named Sheets, and Import into a List
How to Update a Label Inside While Loop in Tkinter
Python Handling Socket.Error: [Errno 104] Connection Reset by Peer