Asynchronous Socket - python

How do I connect with multiple clients? Once connected with multiple clients how do I receive individual data from each? From what I know I need to use something called "Asyncore". How do I implement this?
Client Class
import socket
class Client():
def __init__(self):
self.host = 'localhost'
self.port = 5000
self.s = socket.socket()
self.s.connect((self.host, self.port))
self.s.send(str.encode(input("What is your name ")))
x = Client()
Host Class
import socket
class Host():
def __init__(self):
self.host = 'localhost'
self.port = 5000
self.s = socket.socket()
self.s.bind((self.host, self.port))
self.s.listen(5)
self.c, self.addr = self.s.accept()
print("User from " + str(self.addr) + " has connected")
while True:
data = self.c.recv(1024)
if not data:
break
print(str(self.addr) +" name is " + data.decode("utf-8"))
#c.send(str.encode(whatever))
self.c.close()
x = Host()

Are you looking for this one? asyncore
Here is the link where you can find all the info related to async socket handler
https://docs.python.org/2/library/asyncore.html
EDIT: dano comment is great too
Enjoy

Related

How do multi-threading and infinite loops work together

I'm trying to learn python, doing exercise watching video online. I'm currently trying to do a multi-threading chat server but I think I have trouble understanding the way threads work.
Here's my code:
<!-- language: lang-py -->
import socket
import threading
class ThreadedServer(threading.Thread):
def __init__(self, host, port, buff_size):
threading.Thread.__init__(self)
self.host = host
self.port = port
self.buff_size = buff_size
self.sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.sock.bind((self.host, self.port))
def listen(self):
self.sock.listen(5)
while True:
print('Waiting for a connexion...')
self.c, self.addr = self.sock.accept()
listening = listenToClient(self.c, self.addr)
class listenToClient(threading.Thread):
def __init__(self, client, address):
threading.Thread.__init__(self)
global socks
socks.append(client)
client.send(("Bienvenue sur le serveur, entre ton pseudo: ").encode('utf-8'))
self.name = client.recv(buff_size).decode('utf-8')
welcome = "Welcome " + self.name + "! If ever you want to quit, type {quit}"
client.send(welcome.encode('utf-8'))
msg = self.name + " has joined the chat"
broadcast(msg)
while True:
msg = client.recv(buff_size).decode('utf-8')
if msg != '{quit}':
broadcast(msg, self.name + ": ")
print('TEST6')
else:
client.close()
leave_msg = self.name + " has left"
broadcast(leave_msg)
break
def broadcast(msg, prefix=''):
for sck in socks:
content = prefix + msg
sck.send(content.encode('utf-8'))
def Main():
ThreadedServer(host,port,buff_size).listen()
host = '127.0.0.1'
port = 10000
buff_size = 1024
socks = []
if __name__ == '__main__':
Main()
The code is working ok for only one user.
I think the problem is in my comprehension of threads.
In my mind, when I type
listening = listenToClient(self.c, self.addr)
a new thread is created running in parallel with the first one.
What I see in reality is that my new thread is indeed executing and ends in the infinite loop in here(managing whatever my first user connected is typing):
while True:
msg = client.recv(buff_size).decode('utf-8')
if msg != '{quit}':
broadcast(msg, self.name + ": ")
print('TEST6')
But I thought as the original thread would have continued looping here:
while True:
print('Waiting for a connexion...')
self.c, self.addr = self.sock.accept()
listening = listenToClient(self.c, self.addr)
Printing 'Waiting for a connection' and waiting for a second connection.
But it is not the case.
I'm pretty sure it's a misunderstanding on my side, I spent hours trying and trying changing everything etc, at some point the listenToClient() thread was just a method in the ThreadedServer(). But now I'm very lost and I don't know what to do, so I came here for help.
Thanks in advance,
Vincent

Socket not closing when shutting down a thread

In the below code, although the thread seems to be stopping the socket does not seem to be freed. Not sure what mistake I am making.
When I try to start the second time it is throwing an error 'Address already in use'. I looked up a lot of stack overflow suggestions, did not help much.
Here is my code:
import threading
import time
import socket
class TCPServer(object):
def __init__(self):
self.stop_thread = threading.Event()
def startServer(self, ip="localhost", port=12345):
self.ip = ip
self.port = port
t = threading.Thread(target=self.server, args=(self.stop_thread,
"stop_event"))
t.daemon = True
t.start()
def server(self, stop_event, arg):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((self.ip, self.port))
sock.listen(5)
connection = ""
while not stop_event.is_set():
connection, addr = self.sock.accept()
data = connection.recv(50000)
if data:
connection.send(self.response)
connection.close()
#Tried with below statements - still fails
#self.sock.shutdown(socket.SHUT_RDWR)
#self.sock.close()
def stopServer(self):
self.stop_thread.set()
if __name__ == "__main__":
server = TCPServer()
server.startServer("localhost", 12345)
time.sleep(5)
server.stopServer()
time.sleep(15)
server.startServer("localhost", 12345)
time.sleep(5)
server.stopServer()
I found a work around by forcefully shutting down the socket in stopServer() like below:
def stopServer(self):
self.stop_thread.set()
self.sock.shutdown(socket.SHUT_RDWR)
self.sock.close()
But I dont think this is a good solution. Any suggestions?
import threading
import time
import socket
class TCPServer(object):
def __init__(self):
self.stop_thread = threading.Event()
def startServer(self, ip="localhost", port=12345):
self.ip = ip
self.port = port
t = threading.Thread(target=self.server, args=(self.stop_thread,
"stop_event"))
t.daemon = True
t.start()
def server(self, stop_event, arg):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.bind((self.ip, self.port))
self.sock.listen(5)
connection, addr = self.sock.accept()
while not stop_event.is_set():
data = connection.recv(50000)
if data:
connection.send(self.response)
connection.close()
self.sock.close()
def stopServer(self):
self.stop_thread.set()
so mostly minor things that accumulated. You needed to check if event is set, not just if event was true. You can read more on that in event-object docs. That meant you never left the inner loop. Once you leave the inner loop you need to close both connection and the socket explicitly.

Socket While True Loop Doesn't Work Properly

I want to ask you about while loop in socket works.
The problem is, when i started app, the server is waiting for connections by While True. But if anyone connect, server won't accept another connections. The While True loop freezes.
My Code:
import socket
import threading
class Server(object):
def __init__(self, host="localhost", port=5335):
"""Create socket..."""
self.host = host
self.port = port
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.bind((self.host, self.port))
self.sock.listen(0)
self.clients = []
print("Server is ready to serve on adress: %s:%s..."%(self.host, self.port))
while True:
client, addr = self.sock.accept()
print("There is an connection from %s:%s..."%addr)
t = threading.Thread(target=self.threaded(client, addr))
t.daemon = True
t.start()
self.sock.close()
def threaded(self, client, adress):
"""Thread client requests."""
while True:
data = client.recv(1024)
print("%s:%s : %s"%(adress[0], adress[1], data.decode('ascii')))
if not data:
print("Client %s:%s disconnected..."%adress)
break
if __name__ == "__main__":
Server()
You aren't calling the thread properly. You're calling self.threaded(client, addr) immediately and then passing the result to threading.Thread().
In other words, this:
t = threading.Thread(target=self.threaded(client, addr))
... is identical to this:
result = self.threaded(client, addr)
t = threading.Thread(target=result)
You need to call it like this:
t = threading.Thread(target=self.threaded, args=(client, addr))

Python Socketserver client timeout

I have a socketserver in Python which has to handle multiple clients using the select.select method, as seen in the code below:
import socket
import select
class Server:
def __init__(self):
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind(('localhost', 2000))
self.socket_list = [self.server]
self.addresses = ['localhost']
self.commands = [""]
self.running = True
self.server.listen(10)
def listen(self):
while self.running:
read, write, error = select.select(self.socket_list, [], self.socket_list, 0)
for sock in read:
if sock == self.server and self.running:
try:
conn, address = self.server.accept()
conn.settimeout(30)
self.socket_list.append(conn)
self.addresses.append(address[0])
self.commands.append("")
except:
self.shutdown()
break
elif self.running:
try:
packet = sock.recv(60)
if not packet:
self.close_conn(sock)
index = self.socket_list.index(sock)
self.commands[index] += packet
if '\n' in self.commands[index]:
#handle command
except:
self.close_conn(sock)
def close_conn(self, conn):
#close client conn
def shutdown(self):
#shutdown server
if __name__ == "__main__":
Server().listen()
The problem i currently have is that the client's connection should be closed after 30 seconds, but that doesn't happen, even though i declared that by using conn.settimeout(30). I haven't found any explanation yet as to why this happens.
Note: comments were used to replace parts of the code that didn't mater to the problem.

Python socket server send message to another server in initialize

I want to run a server which accepts connections from a few clients and also want it to send a message to a specific another server -which listen 1234 port- in init time.
self.connect(('localhost', 1234))
self.buffer = 'connect'
I put it in init method. And
made up that kind of code which is below.
class EchoHandler(asyncore.dispatcher_with_send):
def handle_read(self):
data = self.recv(8192)
if data:
print data
self.send(data + " echo")
class EchoServer(asyncore.dispatcher):
def __init__(self, host, port):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr()
self.bind((host, port))
self.listen(5)
self.connect(('localhost', 1234))
self.buffer = 'connect'
def handle_accept(self):
pair = self.accept()
if pair is not None:
sock, addr = pair
print 'Incoming connection from %s' % repr(addr)
handler = EchoHandler(sock)
def handle_write(self):
sent = self.send(self.buffer)
self.buffer = self.buffer[sent:]
server = EchoServer('localhost', 0)
asyncore.loop()
I need your help.. Looking forward your replies. Thank you..

Categories

Resources