I have the next undesirable behaviour:
def run(self):
self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self._socket.bind(("0.0.0.0", self.port()))
self._socket.listen(5)
self._socket.settimeout(5.0)
while not self.finish.isSet():
try:
conn, addr = self._socket.accept()
c = connection(conn, addr)
self.activeconn.append(c)
c.start()
print "New session from address {}".format(addr)
except Exception as e:
print e
self.activeconn = self.child_list()
self._socket.close()
print "Server is closing..."
for conn in self.activeconn:
conn.join()
time.sleep(4)
print "Server is closed"
Here I have echo server with timeout set by settimeout(5.0). The problem is my console prints "timed out" every time timeout is expired. Can I turn this off somehow?
Whenever a timeout occurs during an operation on a socket, the socket.timeout exception is raised. In your code, you are catching that exception and printing it:
try:
conn, addr = self._socket.accept()
# ...
except Exception as e:
print e
If you want to prevent "timed out" lines from appearing in your output, just catch the exception and suppress it:
try:
conn, addr = self._socket.accept()
# ...
except socket.error:
pass
except Exception as e:
print e
Related
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()
I have a server:
import threading
import paramiko
import subprocess
import sys
import socket
host_key = paramiko.RSAKey(filename='test_rsa.key')
class Server(paramiko.ServerInterface):
def _init_(self):
self.event = threading.Event()
def check_channel_request(self, kind, chanid):
if kind == 'session':
return paramiko.OPEN_SUCCEEDED
return paramiko.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
def check_auth_password(self, username, password):
if(username=='justin') and (password == 'lovesthepython'):
return paramiko.AUTH_SUCCESSFUL
return paramiko.AUTH_FAILED
server = sys.argv[1]
ssh_port = int(sys.argv[2])
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((server, ssh_port))
sock.listen(100)
print '[+] Listening for connection ...'
client, addr = sock.accept()
except Exception, e:
print '[-] Listen failed: ' + str(e)
sys.exit(1)
print '[+] Got a connection!'
try:
bhSession = paramiko.Transport(client)
bhSession.add_server_key(host_key)
server = Server()
try:
bhSession.start_server(server=server)
except paramiko.SSHException, x:
print '[-] SSH Negotiation Failed'
chan = bhSession.accept(20)
print '[+] Authenticated!'
print chan.recv(1024)
chan.send('Welcome to bh_ssh')
while True:
try:
command= raw_input("Enter command: ").strip('\n')
if command != 'exit':
chan.send(command)
print chan.recv(1024) + '\n'
else:
chan.send('exit')
print 'exiting'
bhSession.close()
raise Exception ('exit')
except KeyboardInterrupt:
bhSession.close()
except Exception, e:
print '[-] Caught exception: ' + str(e)
try:
bhSession.close()
except:
pass
sys.exit(1)
My code to connect to this is:
import threading
import paramiko
import subprocess
def ssh_command(ip, port, user, passwd, command):
client = paramiko.SSHClient()
#client.load_host_keys('/home/justin/.ssh/known_hosts')
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(ip, port, username=user, password=passwd)
ssh_session = client.get_transport().open_session()
if ssh_session.active:
ssh_session.send(command)
print ssh_session.recv(1024)
while True:
command = ssh_session.recv(1024)
try:
cmd_output = subprocess.check_output(command, shell=True)
ssh_session.send(cmd_output)
except Exception,e:
ssh_session.send(str(e))
client.close()
return
ssh_command('IP_ADDRESS_HERE',PORT_HERE,'justin','lovesthepython','id')
When I try to use these on separate PCs and use public IP addresses it won't connect. The server I bind to 0.0.0.0 and then use the public IP address of the server's computer to the client code. I imagine I am doing something fairly obvious wrong. If anyone can help, it would be very much appreciated.
After long hours of research and testing I finally ask here.
My script has to handle multiple client connections and in the same time has to get and send a stream from another socket.
Finally I've been able to make it work but only for one user. That user connects to the socket, the script connects to the other socket, then return the stream to the client.
The script works pretty well but has a some hard limitations :
- it send the stream to the client but,
- even if the socket is in non-blocking mode I think that calling a socket inside another one is the main reason why it reacts like it was in blocking mode (because one ot these is continuously sending datas ?)
By the way I think that the select() method could allow me to do what I want, but I don't clearly understand how.
Here is the server code taht works for one client, but is blocking
#!/usr/bin/env python
# coding: utf-8
from __future__ import print_function
import sys, time, base64, socket
server_ip = 'XX.XX.XX.XX'
def caster_connect(connected_client, address):
username = 'XXXXXXX'
password = 'XXXXXXXXX'
host = 'XX.XX.XX.XX'
port = 2102
pwd = base64.b64encode("{}:{}".format(username, password).encode('ascii'))
pwd = pwd.decode('ascii')
u_message = ''
stream_type = 'CMRp'
header = \
"GET /" + str(stream_type) + " HTTP/1.1\r\n" +\
"Host " + str(host) + "\r\n" +\
"Ntrip-Version: Ntrip/1.0\r\n" +\
"User-Agent: my_script.py/0.1\r\n" +\
"Accept: */*\r\n" +\
"Authorization: Basic {}\r\n\r\n".format(pwd) +\
"Connection: close\r\n"
print("Connecting to caster...\n")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,int(port)))
s.send(header.encode('ascii'))
print("Waiting answer from caster...\n")
while True:
try:
data = s.recv(2048)
connected_client.send(data)
print("Sending data from caster at %s" % time.time())
sys.stdout.flush()
# On any error, close sockets
except socket.error, e:
print("No data received from caster : %s" % e)
print("Close client connection at %s" % format(address))
s.close()
break
return
#----------------
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((server_ip, 5680))
sock.settimeout(3)
try:
while True:
try:
sock.listen(5)
client, address = sock.accept()
print ("%s connected" % format(address) )
msg = client.recv(4096)
except socket.timeout, e:
err = e.args[0]
if err == 'timed out':
print("Timed out, retry later")
continue
else:
print(socket.error)
sock.close()
except socket.error:
print(socket.error)
sock.close()
else:
if len(msg) == 0:
print("Shutdown on client end")
sock.close()
else:
print(msg)
caster_response = caster_connect(client, address)
sys.stdout.flush()
print("Close")
client.close()
sock.close()`enter code here`
except KeyboardInterrupt:
print("W: Keyboard interrupt, closing socket")
finally:
sock.close()
And this is the code I found to handle select()
#!/usr/bin/env python
# coding: utf-8
import select, socket, sys, Queue
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setblocking(0)
server.bind(('XX.XX.XX.XX', 64000))
server.listen(5)
inputs = [server]
outputs = []
message_queues = {}
while inputs:
readable, writable, exceptional = select.select(
inputs, outputs, inputs)
for s in readable:
if s is server:
connection, client_address = s.accept()
print("New connection from %s" % client_address)
connection.setblocking(0)
inputs.append(connection)
message_queues[connection] = Queue.Queue()
else:
data = s.recv(1024)
print("Data received : %s" % data)
if data:
message_queues[s].put(data)
if s not in outputs:
outputs.append(s)
else:
if s in outputs:
outputs.remove(s)
inputs.remove(s)
s.close()
del message_queues[s]
for s in writable:
try:
next_msg = message_queues[s].get_nowait()
print("Next msg : %s" % next_msg)
except Queue.Empty:
outputs.remove(s)
else:
s.send(next_msg)
for s in exceptional:
inputs.remove(s)
if s in outputs:
outputs.remove(s)
s.close()
del message_queues[s]
In this code (found at this page) I didn't make changes as I don't know how to handle this.
Maybe by creating another server script that would only handle the stream part, so the main script would act as a server for clients, but as client for the stream part ?
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()
My python socket server listens and then connects to a client that will then send a indeterminate number of strings from a user. The client may then close or lose connection to the server.
This causes an error.
[Errno 10053] An established connection was aborted by the software in your host machine.
or
[Errno 10054] An existing connection was forcibly closed by the remote host
How do I handle this event so that I can close the connection and restart my server listening for a reconnect?
Python Server example:
# Echo server program
import socket
import sys
HOST = None # Symbolic name meaning all available interfaces
PORT = 7001 # Arbitrary non-privileged port
s = None
def startListening():
print "starting to listen"
for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC,
socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
af, socktype, proto, canonname, sa = res
try:
s = socket.socket(af, socktype, proto)
except socket.error as msg:
s = None
continue
try:
s.bind(sa)
s.listen(1)
except socket.error as msg:
s.close()
s = None
continue
break
if s is None:
print 'could not open socket'
sys.exit(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
data = conn.recv(1024)
if not data:
break
print data
message = ""
while not "quit" in message:
message = raw_input('Say Something : ')
conn.sendall(message)
#conn.send("I got that, over!")
conn.close()
print "connection closed"
while 1:
startListening()
python client example:
# Echo client program
import socket
import sys
HOST = 'localhost' # The remote host
PORT = 7001 # The same port as used by the server
s = None
for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC, socket.SOCK_STREAM):
af, socktype, proto, canonname, sa = res
try:
s = socket.socket(af, socktype, proto)
except socket.error as msg:
s = None
continue
try:
s.connect(sa)
except socket.error as msg:
s.close()
s = None
continue
break
if s is None:
print 'could not open socket'
sys.exit(1)
s.sendall("Please send me some strings")
data = ""
while ("quit" not in data):
data = s.recv(1024)
print 'Received', repr(data)
s.close()
To reproduce this error, run the server in one command window and the client in a second, then close the client window.
Adding try: except: around the data send and data recv in the server script appears to mitigate the problem:
# Echo server program
import socket
import sys
HOST = None # Symbolic name meaning all available interfaces
PORT = 7001 # Arbitrary non-privileged port
s = None
def startListening():
print "starting to listen"
for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC,
socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
af, socktype, proto, canonname, sa = res
try:
s = socket.socket(af, socktype, proto)
except socket.error as msg:
s = None
continue
try:
s.bind(sa)
s.listen(1)
except socket.error as msg:
s.close()
s = None
continue
break
if s is None:
print 'could not open socket'
sys.exit(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
try:
data = conn.recv(1024)
except:
print "cannot recieve data"
break
if not data:
break
print data
message = ""
while not "quit" in message:
message = raw_input('Say Something : ')
try:
conn.sendall(message)
except Exception as exc:
#print exc # or something.
print "message could not be sent"
break
#conn.send("I got that, over!")
conn.close()
print "connection closed"
while 1:
startListening()
Simply close your side of the connection and be ready to accept a new connection again.
The best way to handle this is to separate the creation of the server socket and the accept/read/write loop:
create_server_socket()
while True:
accept_new_connection();
try:
read_request();
write_response()
finally:
close_connection()
I think when client is closed unexpectedly, that according to SIGPIPE you should handle the signal