Python socket client disconnect

Python Socket – handling client disconnect

I’ve done a lot of research into working with the Sockets class in Python, but I’m having a difficult time understanding how to achieve a solution to my problem. Let me also be clear by saying that I have absolutely no experience with the Python language. The code that I’ve scraped together is from several other examples. It mainly works, I just have one last bug to figure out.

The idea is this script will run on a raspberry pi and that will be the Pi’s sole purpose. Via TCP, you will request an image number, and the Pi will display that particular image full screen. Easy, right?

Again, everything works, except when the ethernet connection to the client is cut, or the client closes the connection. The script then enters a bad infinite loop, the CPU usage maxes out, and I have no choice but to physically power cycle the Pi. I need a way to ensure this won’t happen and make a provision for the client to be able to reestablish a connection to this server in the event of a disconnect/network glitch/etc.

import sys import pygame import SocketServer pygame.init() screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN, 0) pygame.mouse.set_visible(False) imagesequence = [] imagesequence.append(pygame.image.load("/home/pi/appfiles/image1.png") imagesequence.append(pygame.image.load("/home/pi/appfiles/image2.png") screensaver = [] screensaver.append(pygame.image.load("/home/pi/appfiles/screensaver1.png") class MyTCPHandler(SocketServer.StreamRequestHandler): def handle(self): while True: self.data = self.rfile.readline().strip() isNum = False try: int(self.data) isNum = True except ValueError: isNum = False if isNum: framenumber = int(self.data) if framenumber >= 1 and framenumber = 901 and framenumber  

Quitting the script via TCP connection also doesn't work, but I'm not so concerned with that. Eventually, there will never be a reason to quit this.

Best Solution

self.rfile.readline() returns an empty string '' when the socket connection is closed. Make sure to check it before applying .strip() , though, since sending a whitespace-only line will look like an empty string after stripping whitespace.

import socketserver class MyTCPHandler(SocketServer.StreamRequestHandler): def handle(self): while True: self.data = self.rfile.readline() if not self.data: break self.data = self.data.strip() . 

Источник

How do I handle a disconnect with python sockets? (ConnectionResetError)

Solution: This should prevent the server from closing, and clean up clients you had a connection error with: Question: In a TCP client-server communication, when the client attempts to send to the server after the latter has disconnected, the first attempt to (allegedly) succeeds and all subsequent attempts fail with . I'm making a simple server and client with python sockets, and I was wondering how I could handle a disconnect.

How do I handle a disconnect with python sockets? (ConnectionResetError)

I'm making a simple server and client with python sockets, and I was wondering how I could handle a disconnect. Whenever one of my clients disconnects, it gives a ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host and the server stops running. This makes sense, but how can I handle a disconnect like this? Here is my server code: (I know it's messy its my first socket project)

import socket import threading s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #Connection oriented, IPV4 s.bind((socket.gethostname(), 1234))#Ip address information, port s.listen(5) connections = [] #Connection added to this list every time a client connects def accptconnection(): while True: clientsocket, address = s.accept() connections.append(clientsocket) #adds the clients information to the connections array threading.Thread(target=recvmsg, args=(clientsocket, address,)).start() def recvmsg(clientsocket, address): while True: print(f"Connection from has been established.") msg = clientsocket.recv(1024) if len(msg.decode('utf-8')) > 0: print(msg.decode("utf-8")) for connection in connections: #iterates through the connections array and sends message to each one msgbreak = msg connection.send(bytes(str(msgbreak.decode("utf-8")), "utf-8")) accptconnection() 

Thanks in advance if you help!

This should prevent the server from closing, and clean up clients you had a connection error with:

import socket import threading s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #Connection oriented, IPV4 s.bind((socket.gethostname(), 1234))#Ip address information, port s.listen(5) connections = [] #Connection added to this list every time a client connects def accptconnection(): while True: clientsocket, address = s.accept() connections.append(clientsocket) #adds the clients information to the connections array threading.Thread(target=recvmsg, args=(clientsocket, address,)).start() def recvmsg(clientsocket, address): print(f"Connection from has been established.") while True: try: msg = clientsocket.recv(1024) except ConnectionError: print(f"Connection from has been lost.") if clientsocket in connections: connections.remove(clientsocket) return if len(msg.decode('utf-8')) > 0: print(msg.decode("utf-8")) for connection in connections: #iterates through the connections array and sends message to each one msgbreak = msg try: connection.send(bytes(str(msgbreak.decode("utf-8")), "utf-8")) except ConnectionError: print(f"Unable to reach client with socket ") if connection in connections: connections.remove(connection) accptconnection() 

Is detecting a TCP socket disconnect in Python possible?, I think I have most things figured out, but the one question that remains is how to detect sudden client disconnects, and if it's even possible.

Sending to a disconnected socket succeeds the first time [duplicate]

In a TCP client-server communication, when the client attempts to send to the server after the latter has disconnected, the first attempt to send() (allegedly) succeeds and all subsequent attempts fail with [Errno 32] Broken pipe . Minimal example:

import socket import sys import time SERVER_ADDR = ("127.0.0.1", 65432) def server(s): s.bind(SERVER_ADDR) s.listen() print(f"Server listening for clients at ") conn, addr = s.accept() with conn: print("Connected by", addr) def client(s, msg): s.connect(SERVER_ADDR) time.sleep(1) for i in range(1, 10): print(f"Sending - attempt ") try: nbytes = s.send(msg) print(f" bytes sent out of in total") except OSError as ex: print(ex) if __name__ == "__main__": msg = " ".join(sys.argv[1:]).encode("utf8") with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: if msg: client(s, msg) else: server(s) 
python run.py Server listening for clients at ('127.0.0.1', 65432) 
python run.py hello world Sending b'hello world' - attempt 1 11 bytes sent out of 11 in total Sending b'hello world' - attempt 2 [Errno 32] Broken pipe Sending b'hello world' - attempt 3 [Errno 32] Broken pipe Sending b'hello world' - attempt 4 [Errno 32] Broken pipe Sending b'hello world' - attempt 5 [Errno 32] Broken pipe Sending b'hello world' - attempt 6 [Errno 32] Broken pipe Sending b'hello world' - attempt 7 [Errno 32] Broken pipe Sending b'hello world' - attempt 8 [Errno 32] Broken pipe Sending b'hello world' - attempt 9 [Errno 32] Broken pipe 
  • Why does this happen?
  • How can I either (a) make the first attempt fail too, or (b) detect if the connection is alive before sending?

There is a detailed explanation in this answer to Writing to a closed, local TCP socket not failing.

How can I either (a) make the first attempt fail too, or (b) detect if the connection is alive before sending?

You can make the first attempt fail by forcing the server to close the socket immediately, with the SO_LINGER socket option, after the s.accept line:

conn.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 0)) 

Exit Python While Loop when socket disconnects, You should receive a socket disconnection exception, or empty data (as you tested in the if) in case of a disconnection.

Python Socket - handling client disconnect

I've done a lot of research into working with the Sockets class in Python, but I'm having a difficult time understanding how to achieve a solution to my problem. Let me also be clear by saying that I have absolutely no experience with the Python language. The code that I've scraped together is from several other examples. It mainly works, I just have one last bug to figure out.

The idea is this script will run on a raspberry pi and that will be the Pi's sole purpose. Via TCP, you will request an image number, and the Pi will display that particular image full screen. Easy, right?

Again, everything works, except when the ethernet connection to the client is cut, or the client closes the connection. The script then enters a bad infinite loop, the CPU usage maxes out, and I have no choice but to physically power cycle the Pi. I need a way to ensure this won't happen and make a provision for the client to be able to reestablish a connection to this server in the event of a disconnect/network glitch/etc.

import sys import pygame import SocketServer pygame.init() screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN, 0) pygame.mouse.set_visible(False) imagesequence = [] imagesequence.append(pygame.image.load("/home/pi/appfiles/image1.png") imagesequence.append(pygame.image.load("/home/pi/appfiles/image2.png") screensaver = [] screensaver.append(pygame.image.load("/home/pi/appfiles/screensaver1.png") class MyTCPHandler(SocketServer.StreamRequestHandler): def handle(self): while True: self.data = self.rfile.readline().strip() isNum = False try: int(self.data) isNum = True except ValueError: isNum = False if isNum: framenumber = int(self.data) if framenumber >= 1 and framenumber = 901 and framenumber  

Quitting the script via TCP connection also doesn't work, but I'm not so concerned with that. Eventually, there will never be a reason to quit this.

self.rfile.readline() returns an empty string '' when the socket connection is closed. Make sure to check it before applying .strip() , though, since sending a whitespace-only line will look like an empty string after stripping whitespace.

import socketserver class MyTCPHandler(SocketServer.StreamRequestHandler): def handle(self): while True: self.data = self.rfile.readline() if not self.data: break self.data = self.data.strip() . 

After relentless code digging, I cannot answer the first part. It looks like there is no way at this high level for you to detect a socket closing. Look into the (out of favor, I think, but perfectly usable) asyncore and asynchat modules.

As for the second part, you need to break from the loop on receiving a 'q'.

Tongue in cheek code sample:

Python Socket Programming, Python Socket Example · Python socket server program executes at first and wait for any request · Python socket client program will initiate the

Источник

Python socket client disconnect

Subreddit for posting questions and asking for general advice about your python code.

Hi so I have this Python socket chat program and how would I know when a client has disconnected?

What i have so far: I am running a daemon thread on each client connected to my server, it's called "handle" because it's handling each client/socket individually in a thread.

clients = [] #active clients nicknames = [] #active nicknames def handle(client): """This function will be run on every connected client, and will be recieving messages and broadcasting them to all clients connected.""" while True: try: message = client.recv(1024).decode('utf-8') print(f'Recieved ') broadcast(message) #for broadcasting to all clients connected the message except: print('something went wrong. ') tmp = client # A temp variable for refering to client after removal client.close() #close connection to client nickname = nicknames[clients.index(client)] clients.remove(client) #remove the client from active clients broadcast(f' has left the chat!') nicknames.remove(nickname) #remove the nickname from active nicknames break

So it will run in a daemon thread on every connected client/socket and will wait for a message to be recieved and then send the message to all other clients connected. The problem I am facing is that when ever a client disconnects it spams "recieved " in the console. So apparently the client sends empty bytes strings to the server after the client's program have been terminated, but what I think should happen is that

message = client.recv(1024).decode('utf-8') should raise an exception, and then trigger the exception block whenever a client disconnects, instead of recieving empty byte strings.

So my question is why is it not raising an exception and running the exception block?

Источник

Читайте также:  Python выполнить команду powershell
Оцените статью