I'm creating a simple socket chatting application and I tried to make something that handles somebody terminating the client connected to the server, but it seems to ignore it and I get the connection forcibly closed by the remote host exception.
Here's some of the code
clients = []
class client(Thread):
def __init__(self, socket, address):
Thread.__init__(self)
self.sock = socket
self.addr = address
self.start()
def run(self):
while 1:
msg = self.sock.recv(1024).decode()
#This if not statement is ignored
if not msg:
clients.remove(socket)
print str(adress[0]) + ":" + str(adress[1]) + " disconnected"
quitm = str(adress[0]) + ":" + str(adress[1]) + " disconnected"
for client in clients:
client.send(quitm.encode())
socket.close()
break
print msg
for client in clients:
client.send(msg.encode())
I've been searching up for some solutions but haven't found any. Any help is appreciated!!!
If the thing at the other end closes the connection normally, that is indicated by recv() returning zero bytes. However, if the thing at the other end terminates without closing the connection, that is considered an abnormal situation which indicated by recv() raising an exception. You need to use a try/catch block to handle that exception.
Related
I have a problem where I need to store data on a disk when the TCP socket disconnects for whatever reason that would otherwise be sent over that socket and simultaneously check when a new connection is established and I can't find a solution to this.
What I have is:
def start_server_for_clients(srv, port):
client = None
try:
srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
srv.bind(('', port))
srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
srv.listen(5)
print('Waiting for clients on port %s' % port)
while True:
client, address = srv.accept()
client.settimeout(10)
print('Connected client %s %s.' % (address[0], address[1]))
t = threading.Thread(target=handle_client, args=(client, address))
t.daemon = True
t.start()
except Exception as e:
print(e)
if client:
client.close()
handle_client is a function where data is processed and sent over the socket every second in a while loop. I need that processed data either way: connected or not and store it.
Now my logic to separate data processing and socket communication into different parts but where does it fit into threading once the connection is back up again because I would need to clear off the stored data first while simultaneously storing/buffering newly accumulated data and only then proceed to instant communication between sockets? Do I need to use select in this thread and spawn another one to for storing and recovering?
I have this problem with a portscanner which keeps hanging at scanning port 1. How can I solve this problem?
#! /usr/bin/env python
import socket
import subprocess
from datetime import datetime
#Clear the screen
subprocess.call('clear', shell=True)
def portscan():
server = raw_input("Enter the server to scan: ")
serverIP = socket.gethostbyname(server)
# Printing banner with information about host
print "[+] Host: {} [+]\nIP Address: {}\n".format(server, serverIP)
print "[!] Please wait, scanning for open services...\n"
#Time when scan started.
t1 = datetime.now()
try:
for port in range(1, 1024):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = sock.connect_ex((serverIP, port))
if result == 0:
print "[+] Port {}: Status:OPEN\n".format(result)
sock.close()
except socket.gaierror:
print "Hostname could not be resolved, Exiting...\n"
sys.exit()
except socket.error:
print "Couldn\'t connect to server, Exiting\n"
sys.exit()
#Checking time again
t2 = datetime.now()
#Calculate duration of scan
totaltime = t2 - t1
print "Scan completed, duration: {}\n".format(totaltime)
What happens when i run it i give it a hostname and resolve it to a IP
Address but whenever the scan starts it keeps scanning port 1 as i saw
in Wireshark
I think that you maybe need a timeout.
Eventually, your sock.connect_ex( ), will to raise an exception socket.error: [Errno 110] Connection timed out, as you can read more about it, in this answer.
But the default timeout could be 120 seconds, and maybe you don't want to wait so much. So, you can set your own timeout, like that:
try:
for port in range(1, 1024):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(10) #timeout set for wait up 10 seconds.
result = sock.connect_ex((serverIP, port))
sock.settimeout(None)
To know why to use sock.settimeout(None), and see another ways of setting timeout, you can read this discussion.
I'm not sure if it was what you're looking for, but I hope it may help.
I am wondering why my portScanner module runs and claims that all my ports are closed?
I am running Python 2.7 because thats what Violent Python(the book) uses.
Only solution I have tried so far was I have set my DNS to 8.8.8.8 and secondary to 8.8.4.4 because my socket takes 'www.google.com' as the Ip.
Code:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serverIp = socket.gethostbyname('www.google.com')
def pscan(port):
try:
s.connect((serverIp,port))
return True
except:
return False
for x in range(1,101):
if pscan(x):
print("Port %d is open!!!" % (x))
else:
print("Port %d is closed" % (x))
You only create a single socket and try to use it in multiple connect's. This is not possible. If you look at the details of the Exception you will notice that the first one (port 1) fails slowly because the connect timed out but the following ones all fail quickly because of "Operation already in progress".
The fix is to create a new socket before each connect. Additionally it might be helpful to reduce the time it tries to connect with s.settimeout(1).
There is a server for a single client. Client can connect and disconnect at any time
Here is simplified code
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
while true:
a = s.accept()
try:
data = a[0].recv(1024)
except socket.error:
a[0].close()
print 'cought the error'
It works, but socket.error generation takes random amount of time from few seconds up to a minute. May this value be managed?
If the client disconnects, there is no socket.error, rather recv() returns an empty string immediately. Besides, you are not closing the connection in this case.
In my python program (2.7), I attempt to create a thread but it instantly starts when it is created, not when the start() and then the run() attributes are called. Help would be great.
Here is my (server) code:
import sys
import socket
import threading
global connections
connections = []
def srcv(s, conn, data):
while True:
print "Recieving"
#Recieve Strings From Each Connection
for i, n in enumerate(connections):
data.append([connections[1], i.recv(4096)])
#Send String To Each Connection
print "Sending"
for i, n in enumerate(connections):
i.send("{0}: {1}".format(data[n][0], data[n][1]))
def listn(s, conn, data):
s.listen(10)
print "Listening For Connection"
while True:
obj, addr = s.accept()
connections.append([obj, addr])
def start_server():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conn = []
data = []
s.bind(("localhost", 12345))
print "Creating Listening Thread"
listen = threading.Thread(target=listn(s,conn,data))
print "Preparing Listening Thread"
listen.start()
print "Starting Listening Thread"
listen.run()
print "Creating Send/Receive Thread"
sandr = threading.Thread(target=srcv(s, conn, data))
print "Preparing Send/Receive Thread"
sandr.start()
print "Connections Now Acceptable"
sandr.run()
if __name__ == '__main__':
sys.exit(start_server())
Please let me know if my code seems clunky/disorganized, I am somewhat new to programming in general.
EDIT:
Another problem I encountered is that I cannot run both of the threads, as when one starts, the other can not be. Why is that, and how can I fix it?
You need to use put the arguments in args= so that the function is not called before listen.start():
listen = threading.Thread(target=listn, args=(s,conn,data))
Not
listen = threading.Thread(target=listn(s,conn,data))
Also you shouldn't call .run(), .start() does that internally on the newly started thread. Therun method is there so that subclasses of Thread can override it.