Python Tcp disconnect detection - python

I have a simpletcp example:
import socket
import time
TCP_IP = '127.0.0.1'
TCP_PORT = 81
BUFFER_SIZE = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
while True:
s.send(bytes('hello', 'UTF-8'))
time.sleep(1)
s.close()
How can I detect, if I lost the connection to the server, and how can I safely reconnect then?
Is it necessary to wait for answer to the server?
UPDATE:
import socket
import time
TCP_IP = '127.0.0.1'
TCP_PORT = 81
BUFFER_SIZE = 1024
def reconnect():
toBreak = False
while True:
s.close()
try:
s.connect((TCP_IP, TCP_PORT))
toBreak = True
except:
print ("except")
if toBreak:
break
time.sleep(1)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
while True:
try:
s.send(bytes('hello', 'UTF-8'))
print ("sent hello")
except socket.error as e:
reconnect()
time.sleep(1)
s.close()
If I break the connection, it raises an error (does not really matter what), and goes to the
reconnect loop. But after I restore the connection, the connect gives back this error:
OSError: [WinError 10038] An operation was attempted on something that is not a socket
If I restart the script, which calls the same s.connect((TCP_IP, TCP_PORT)), it works fine.

You'll get a socket.error:[Errno 104] Connection reset by peer exception (aka ECONNRESET) on any call to send() or recv() if the connection has been lost or disconnected. So to detect that, just catch that exception:
while True:
try:
s.send(bytes('hello', 'UTF-8'))
except socket.error, e:
if e.errno == errno.ECONNRESET:
# Handle disconnection -- close & reopen socket etc.
else:
# Other error, re-raise
raise
time.sleep(1)

Use a new socket when you attempt to reconnect.
def connect():
while True:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
return s.makefile('w')
except socket.error as e:
log("socket error {} reconnecting".format(e))
time.sleep(5)
dest = connect()
while True:
line = p.stdout.readline()
try:
dest.write(line)
dest.flush()
except socket.error as e:
log("socket error {} reconnecting".format(e))
dest = connect()

Can you try that (I think that you does'not try socket.SO_REUSEADDR):
def open_connection():
data0=''
try:
# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# Connect the socket to the port where the server is listening
server_address = ('192.168.0.100', 8000)
sock.settimeout(10) # TimeOut 5 secunde
while True:
try:
sock.connect(server_address)
message = 'new connection'
sock.sendall(message)
# Look for the response
amount_received = 0
data0=sock.recv(1024)
amount_received = len(data0)
return
finally:
wNET = 0
pass
except:
sock.close()
time.sleep(60)
del data0

This is the code based on thread. The main tip is that the received buffer cannot be none, if the socket is connected.
import time
import socket
import threading
def connect():
while True:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.settimeout(60)
return s
except socket.error as e:
print("socket error {} reconnecting".format(e))
time.sleep(5)
soc = connect()
def runSocket():
global soc
while True:
try:
recBuf = soc.recv(64)
if recBuf == b'': #remote server disconnect
soc = connect()
else:
print(recBuf)
except socket.timeout:
print("Timeout")
except Exception as e:
print("other socket error {}".format(e))
soc = connect()
socketThread = threading.Thread(target=runSocket)
socketThread.start()

Related

socket python library. client crashes

I start the server, then the client, the server gets the data and the client does not get a response, crashes
server
import pygame, socket, time
pygame.init()
main_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
main_socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
main_socket.bind(("localhost", 10000))
main_socket.setblocking(0)
main_socket.listen(5)
players_sockets = []
while True:
try:
new_socket, addr = main_socket.accept()
print("Connect", addr)
new_socket.setblocking(0)
players_sockets.append(new_socket)
except:
pass
for i in players_sockets:
try:
data = i.recv(1024)
data = data.decode()
except:
pass
for i in players_sockets:
try:
i.send("server data").encode()
except:
players_sockets.remove(i)
print("Disconnect")
i.close()
time.sleep(1)
client
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
sock.connect(("localhost", 10000))
while True:
sock.send("Command".encode())
data = sock.recv(1024)
data = data.decode()
print(data)
error:
" data = sock.recv(1024)
ConnectionAbortedError: [WinError 10053] The program on your host computer has broken an established connection."

Server is receiving data even after connection closed

I'm sending a file to the client. It works great. But when i'm sending a big file and close the client's terminal suddenly(which is sending data at that time), server doesn't stop writing the data.(After I close the connection(terminal of the client), more time I wait, more server’s file get bigger.)I want to make system protected against error because i may encounter this problem. The still-working part (in server)is:
while True:
data = conn.recv(4096)
if not data:
break
f.write(data)
server.py:
import time
import socket
port = 3030
s = socket.socket()
host = '' #public ip(aws)
s.bind((host, port))
s.listen(5)
print ('Server listening....')
def resultf(supp):
return 'calculated'
while True:
try:
conn, addr = s.accept()
print ('Got connection from', addr)
supp = conn.recv(1024)
print('Server received', supp.decode('utf-8'))
conn.send(supp)
with open('tobecalculated.txt', 'wb') as f:
while True:
data = conn.recv(4096)
if not data:
break
f.write(data)
conn.close()
result=resultf(int(supp))
conn, addr = s.accept()
conn.send(str(result).encode())
print('Done sending')
except Exception as E:
print(E)
try:
conn.send(b"Exception occurred. Try again")
except Exception as SendError:
pass
finally:
conn.close()
client.py:
import socket
import time
try:
s = socket.socket()
host='' # Server public ip
port =3030
s.connect((host, port))
supp=1
s.send(str(supp).encode("utf-8"))
print(s.recv(1024).decode())
with open('tobecalculated.txt', 'rb') as f:
l = f.read()
while (l):
s.send(l)
l = f.read()
s.shutdown(socket.SHUT_WR)
s.close()
while True:
try:
s = socket.socket()
s.connect((host, port))
print('Receiving')
result = s.recv(1024)
print('Received:')
break
except Exception as calc:
print('Calculating... Please wait',calc)
with open('file.txt', 'wb') as f:
f.write(result)
print(result.decode())
s.close()
print('Connection closed')
except Exception as E:
print(E)
Lastly, I tried(after closing connection/terminal) this to see if data is same but it says 'not same'
import time
import socket
port = 3030
s = socket.socket()
host = '' #public ip(aws)
s.bind((host, port))
s.listen(5)
print ('Server listening....')
def resultf(supp):
return 'calculated'
while True:
try:
conn, addr = s.accept()
print ('Got connection from', addr)
supp = conn.recv(1024)
print('Server received', supp.decode('utf-8'))
conn.send(supp)
global a
a=0
index=0
with open('tobecalculated.txt', 'wb') as f:
while True:
data = conn.recv(4096)
if data==a:
print('same',index)
else:
print('not same',index))
index+=1
a=data
if not data:
break
f.write(data)
conn.close()
result=resultf(int(supp))
conn, addr = s.accept()
conn.send(str(result).encode())
print('Done sending')
except Exception as E:
print(E)
try:
conn.send(b"Exception occurred. Try again")
except Exception as SendError:
pass
finally:
conn.close()

How can I receive multiple messages from one connection?

I have a server and I need it to receive multiple connections and messages.
The server receives new connections without problems but it doesn't get multiple messages from one connection.
import socket
import select
HEADER_LENGTH = 1024
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
server_socket.bind((HOST, PORT))
except socket.error as e:
print(str(e))
print("Server is connected")
server_socket.listen(5)
sockets_list = [server_socket]
clients = {}
print("Server is listening")
def receive_message(conn):
try:
data = conn.recv(HEADER_LENGTH)
if not len(data):
return False
strdata = data.decode('utf-8')
print(strdata)
return strdata
except Exception as e:
print(e)
return False
def handle_client():
conn, addr = server_socket.accept()
print(f"Accepted new connection from {addr[0]}:{addr[1]}")
sockets_list.append(conn)
while True:
read_sockets, _, exception_sockets = select.select(sockets_list, [], [], 0)
for i in read_sockets:
if i == server_socket:
handle_client()
else:
print("received message")
message = receive_message(i)
if message is False:
sockets_list.remove(i)
try:
del clients[i]
except KeyError:
pass
continue
if message is not None:
clients[i] = message
if message is not None:
for client_socket in clients:
if client_socket != i:
client_socket.send(str.encode(message))
print("sent to all players")
What happens it that after receiving the first message, the server stops receiving messages from that connection.
And of course there is a lot more code but I showed you the relevant code.
I'll be very happy if someone helps me with that, I've surfed the web so much but haven't seen a solution for my problem.
updates:
I've tried to put socket.close() on my client side(written in Java) and then server gets maximum 2 messages and the problems with it are:
1. The server gets maximum 2 messages.
2. the connection changes(I need that the connection will stay static if possible)
try this code block
#-*- coding:utf-8 -*-
import socket
import sys
#get machine ip address
server_ip = socket.gethostbyname(socket.gethostname())
#create socket object
s = socket.socket()
#define port number
port = 6666
#bind ip and port to server
s.bind((server_ip,port))
#now waiting for clinet to connect
s.listen(5)
print("Enter this ip to connect your clinet")
print(server_ip)
clients = []
flag = True
recv_data = ""
if not clients:
c, addr = s.accept()
print("this is c ",c," this is Addr ",addr)
clients.append(c)
recv_data = c.recv(1024)
print(recv_data.decode("utf-8"))
if flag == True:
while recv_data.decode("utf-8") != "EX":
recv_data = c.recv(1024)
recv_data.decode("utf-8")
if recv_data.decode("utf-8") == "EX":
s.close()
print("check false")
break
s.close()

How to send data to client with conn.send()

Im trying to create a simple chat server. I've been able to send information to the server through the client using 'client.send()' but I cannot seem to do the same server->client
I have tried using methods such as conn.send() and conn.sendall(), but (I guess since the code is in a try) they seem to get skipped after the initial conn.send(str.encode("Connected"))
Server code
import socket
from _thread import *
import sys
server = "192.168.0.4"
port = 5555
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.bind((server, port))
except socket.error as e:
str(e)
s.listen(2)
print("Waiting for a connection, Server Started")
def threaded_client(conn):
conn.send(str.encode("Connected"))
reply = ""
while True:
conn.send(str.encode(str(reply)))
try:
data = conn.recv(2048*1)
reply = data.decode("utf-8")
if not data:
print("Disconnected")
break
else:
print("Received: ", reply)
print("Sending : ", reply)
conn.sendall(str.encode(reply)) #Where I want to send information to the client
except:
break
print("Lost connection")
conn.close()
while True:
conn, addr = s.accept()
print("Connected to:", addr)
start_new_thread(threaded_client, (conn,))
client code
import socket
class Network:
def __init__(self):
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server = "192.168.0.4"
self.port = 5555
self.addr = (self.server, self.port)
self.id = self.connect()
print(self.id)
def connect(self):
try:
self.client.connect(self.addr)
return self.client.recv(2048).decode()
except:
pass
def send(self, data):
try:
self.client.send(str.encode(data))
return self.client.recv(2048).decode()
except socket.error as e:
print(e)
from network import Network
n = Network()
while True:
n.send("sending stuff") #this works/sends properly
You forgot to use print() to display data from server
while True:
print( n.send("sending stuff") )
BTW: in server you send the same data two times - with conn.send() and conn.sendall()

Why I do not caught socket timeout?

I do not understand, why in this code below I do not have the timeout (even if I set it with settimeout, I cant see the exception caught):
import socket
HOST = 'x.x.x.x'
open_ports = []
closed_ports = []
def scan(PORT):
sock_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#sock_tcp.settimeout(0.5)
SERVER_ADDR = (HOST, PORT)
try:
portStatusTCP = sock_tcp.connect_ex(SERVER_ADDR)
if portStatusTCP==0:
open_ports.append(PORT)
print(str(PORT)+' is OPEN')
else:
closed_ports.append(PORT)
print(str(PORT)+' is CLOSED')
except socket.error as socketerror:
print("ERROR"+socketerror)
sock_tcp.close()
for PORT in range(15,25):
print('scanning port: '+str(PORT))
scan(PORT)
print(open_ports)
print(closed_ports)

Categories