Server is receiving data even after connection closed - python

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()

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."

How to limit number of connections to server socket

I'm trying to have multiple clients connect to a server socket and transfer data between them, however I want to limit the number of connections that can be made to the server/ number of client processes to 3. How can I do this?
server:
import socket
from _thread import *
PORT = 5050
HOST = socket.gethostbyname(socket.gethostname())
ADDR = (HOST, PORT)
ThreadCount = 0
tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
tcp.bind(ADDR)
except socket.error as e:
print(str(e))
print("Awaiting connection")
tcp.listen(5)
def threaded_client(connection):
connection.send(str.encode('Welcome to sv'))
while True:
data = connection.recv(2048)
reply = 'Server returns: ' + data.decode('utf-8')
if not data:
break
connection.sendall(str.encode(reply))
connection.close()
while True:
Client, address = tcp.accept()
print('Connected to: ' + address[0] + ':' + str(address[1]))
start_new_thread(threaded_client, (Client, ))
ThreadCount += 1
print('Number of threads: ' + str(ThreadCount))
ServerSocket.close()
client:
import socket
Client = socket.socket(socket.AF_INET, socket. SOCK_STREAM)
PORT = 5050
HOST = socket.gethostbyname(socket.gethostname())
ADDR = (HOST, PORT)
print('Awaiting connection')
try:
Client.connect(ADDR)
except socket.error as e:
print(str(e))
Response = Client.recv(1024)
while True:
Input = input('Sends Info: ')
Client.send(str.encode(Input))
Response = Client.recv(1024)
print(Response.decode('utf-8'))
Cliente.close()

data_arr = pickle.loads(data) EOFError: Ran out of input

When my server receives the pickle.dumps data and loads it pickle.loads (data) it generates the following error
data_arr = pickle.loads (data)
EOFError: Entry timed out
import socket
import pickle
HOST = 'localhost'
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print ('Connected by', addr)
while 1:
data = conn.recv(4096)
data_arr = pickle.loads(data)
if not data: break
conn.send(data)
conn.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()

Python Tcp disconnect detection

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()

Categories