Open jackjindtnt opened 7 years ago
Let's make a brief introduction to Sockets in python, what first is to import them import socket
can be defined as follows sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
is associated with a host with the bind method, which receives parameter a tuple sock.bind( (str( host ), int( port ) ) )
and glue a couple of connections before rejecting any sock.listen(10)
With this we have a blocking type socket, but what is the problem? Let's try to explain it by means of an example:
the problem is that the server stays let's say that plugged into one connection and puts the others on hold, which for the Creating a chat is not convenient.
What is the solution ? It would be to call the setblocking method which receives a parameter of Boolean type self.sock.setblocking(False)
Let's go with the chat we import the bookstores
import socket import threading import sys import pickle
a pickle library allows us to serialize messages to be able Send them in the form of bytes.
Client
class Cliente(): def init(self, host="localhost", port=7000): self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.connect((str(host), int(port)))
we have the socket ready, now to read all the messages that send the server we use a thread ... If you have doubts about the threads at the end I will leave some links
def init(self, host="localhost", port=7000): ..... msg_recv = threading. Thread(target=self.msg_recv) msg_recv.daemon = True msg_recv.start()
now we create a cycle that will keep the main thread alive and we will allow to write the messages.
def init(self, host="localhost", port=7000): ..... while True: msg = input('-> ') if msg != 'salir': self.send_msg(msg) else: self.sock.close() sys.exit()
we define the function msg_recv :
def msg_recv(self): while True: try: data = self.sock.recv(1028) if data: data = pickle.loads(data) print(data) except: pass
This is nothing more than an endless while, which will always be pending to the messages that the server sent to show them on the screen
Now we define the function to send the send_msg messages
def send_msg(self, msg): try: self.sock.send(pickle.dumps(msg)) except: print('error')
Server
we create the server class and define its constructor by passing it per parameter the host and the port for socket creation
class Servidor(): def init(self, host="localhost", port=7000):
clientes conectados self.clientes = [] self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.bind((str(host), int(port))) self.sock.listen(10) self.sock.setblocking(False)
las conexiones aceptar = threading .Thread(target=self.aceptarCon) procesar = threading .Thread(target=self.procesarCon) aceptar.daemon = True aceptar.start() procesar.daemon = True procesar.start()
we create the while that will keep the main thread alive
def init(self, host="localhost", port=7000): ... try: while True: msg = input('-> ') if msg == 'salir': break self.sock.close() sys.exit() except: self.sock.close() sys.exit()
we define the function that will allow us to send the messages to all connected clients def msg_to_all(self, msg, cliente): for c in self.clientes: try: if c != cliente: c.send(msg) except: self.clientes.remove(c)
we define the function that will accept the connections and store them in the customer arrangement
def aceptarCon(self): print("aceptarCon iniciado") while True: try: conn, addr = self.sock.accept() conn.setblocking(False) self.clientes.append(conn) except: pass
finally we define the function to process the connections, this will contain an infinite while that will be going through the list of clients to know when he receives a message.
def procesarCon(self): print("ProcesarCon iniciado") while True: if len(self.clientes) > 0: for c in self.clientes: try: data = c.recv(1024) if data: self.msg_to_all(data,c) except: pass
//code 1//
//SERVER//
import socket import time
host = '127.0.0.1' port = 5000
clients = []
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.bind((host,port)) s.setblocking(0)
quitting = False print "Server Started." while not quitting: try: data, addr = s.recvfrom(1024) if "Quit" in str(data): quitting = True if addr not in clients: clients.append(addr)
s.close()
//CLIENT//
import socket import threading
tLock = threading.Lock() shutdown = False
def receving(name, sock): while not shutdown: try: tLock.acquire() while True: data, addr = sock.recvfrom(1024) print str(data) except: pass finally: tLock.release()
host = '127.0.0.1' port = 0
server = ('127.0.0.1',5000)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.bind((host, port)) s.setblocking(0)
rT = threading.Thread(target=receving, args=("RecvThread",s)) rT.start()
alias = raw_input("Name: ") message = raw_input(alias + "-> ") while message != 'q': if message != '': s.sendto(alias + ": " + message, server) tLock.acquire() message = raw_input(alias + "-> ") tLock.release() time.sleep(0.2)
shudown = True rT.join() s.close()