Red de conocimiento informático - Problemas con los teléfonos móviles - Cómo crear un servidor de socket en Python

Cómo crear un servidor de socket en Python

Los servidores de socket se pueden subdividir en varios tipos, tcp, udp, websocket, todos llaman al módulo de socket, pero existen ligeras diferencias en la implementación específica

Vamos a darle primero una ejemplo de una sala de chat implementada por tcp y udp a través del protocolo socket

Sala de chat de Python (versión python2.7):

Ambos ejecutan server.py y client.py respectivamente. ahora es posible.

Versión TCP: socket-tcp-server.py (servidor):

#-*-?encoding:utf-8?-*-

# socket.getaddrinfo(host,?port,?family=0,?socktype=0,?proto=0,?flags=0)

#Según el parámetro host/puerto dado, la conversión correspondiente a cinco tuplas que contienen una tupla de cinco utilizadas para crear un objeto de socket,

#El parámetro host es el nombre de dominio, proporcionado en forma de cadena para representar una dirección IPV4/IPV6 o Ninguna.

#Parameter Si el puerto está en forma de cadena, representa un nombre de servicio, como "http", "ftp", "email", etc., o es un número, o Ninguno

#La familia de parámetros es la familia del propietario, que puede ser AF_INET?, AF_INET6?, AF_UNIX.

#El parámetro socktype puede ser SOCK_STREAM (TCP) o SOCK_DGRAM (UDP)

# El parámetro proto suele ser 0 y se puede ignorar directamente

#Los indicadores de parámetro son una combinación de AI_*, como AI_NUMERICHOST, que afectará el valor de retorno de la función

#Nota : Pasar Ninguno a los parámetros host y puerto se basa en C, pasando NULL.

#Esta función devuelve una tupla de cinco (familia,?socktype,?proto,?canonname,?sockaddr), y el quinto parámetro sockaddr también es una tupla (dirección,?puerto)

#Para obtener más métodos y enlaces, visite

#?Echo?server?program

from?socket?import?*

import ?sys

¿importar?threading

desde?time?import?ctime

desde?time?import?localtime

importar?traceback

¿importar?tiempo

importar?subproceso

recargar(sys)

sys.setdefaultencoding("utf8")

HOST='127.0.0.1'

PORT=8555?#Establecer puerto de escucha

BUFSIZ=1024

clase?TcpServer():

def?__init__(self):

self.ADDR=(HOST,?PORT)

prueba:

self.sock= socket(AF_INET ,?SOCK_STREAM)

imprimir?'%d?is?open'?%?PORT

self.sock.bind(self.ADDR)

self .sock.listen(5)

#Establecer condiciones de salida

self.STOP_CHAT=False

#?Todos los clientes que escuchan

self .clients?=?{}

self.thrs?=?{}

self.stops?=?[]

excepto ?Exception,e:

imprimir?"%d?is?down"?%?PORT

return?False

def?IsOpen(ip,? puerto):

s?=?socket(AF_INET,?SOCK_STREAM)

prueba:

s.connect((ip,?int(puerto)) )

#?s.shutdown(2)

#?Utilice la función Shutdown() para cambiar la transmisión de datos bidireccional del socket a una transmisión de datos unidireccional. Shutdown() requiere un parámetro separado,

#? Este parámetro indica cómo cerrar el socket. Específicamente: 0 significa prohibir la lectura futura; 1 significa prohibir la escritura futura; 2 significa prohibir la lectura y escritura futuras.

imprimir?'%d?is?open'?%?port

retorno?Verdadero

excepto:

imprimir?' %d?is?down'?%?port

return?False

def?listen_client(self):

mientras?not?self.STOP_CHAT:

print(estás esperando acceso, puerto de escucha:%d'?%?(PORT))

self.tcpClientSock,?self.addr=self.sock.accept ( )

print(u' acepta conexión, dirección del cliente: ', self.addr)

dirección?=?self.addr

# se establecerá Put el enlace client?socket en la lista self.clients

self.clients[address]?=?self.tcpClientSock

#Coloque cada enlace establecido en el proceso respectivamente, reciba y distribuya mensajes

self.thrs[dirección]?=?threading.Thread(target=self.readmsg,?args=[dirección])

self.thrs[dirección ].start( )

time.sleep(0.5)

def?readmsg(self,address):

#Si la dirección no existe, devuelve False

if?address?not?in?self.clients:

return?False

#Obtener el socket del cliente que envió el mensaje

client?=?self.clients[dirección]

mientras?True:

intenta:

#Obtener los datos del contenido del mensaje

data=client.recv(BUFSIZ)

excepto:

print(e)

self.close_client(dirección)

romper

if?not?data:

break

#python3 usa bytes, por lo que debe codificarse

#s='% s La información que me enviaron es: [%s]?%s'?%(addr[0],ctime(),?data.decode('utf8'))

#Formatear la fecha

ISOTIMEFORMAT='%Y-%m-%d?%X'

stime=time.strftime(ISOTIMEFORMAT,?localtime())

El la información que me envió s=u'%s es: %s'?%(str(address),data.decode('utf8'))

#¿Distribuir el mensaje obtenido al cliente de enlace? socket

para?k?in?self.clients:

self.clients[k].send(s.encode('utf8'))

self.clients[k].sendall('sendall:'+s.encode('utf8'))

print?str(k)

print([stime] ,? ':',?data.decode('utf8'))

#Si ingresa quit (ignorando mayúsculas y minúsculas), el programa saldrá

<

p>STOP_CHAT=(data.decode('utf8').upper()=="SALIR")

if?STOP_CHAT:

imprimir?"salir"

self.close_client(dirección)

imprimir?"ya?salir"

romper

def?close_client(self,dirección):

pruebe:

client?=?self.clients.pop(dirección)

self.stops.append(dirección)

client.close ()

para?k?in?self.clients:

self.clients[k].send(str(dirección)?+?u"Ya se fue")

excepto:

pasar

print(str(dirección)+u'Salido')

if?__name__?== '__main__ ':

tserver?=?TcpServer()

tserver.listen_client() ——————————Hermosa línea divisoria—————— ——— — socket-tcp-client.py? (cliente):

#-*-?encoding:utf-8?-*-

from?socket?import ?*

importar?sys

importar?threading

importar?tiempo

recargar(sys)

sys.setdefaultencoding( "utf8")

#Prueba, conéctate a esta máquina

HOST='127.0.0.1'

#Establecer puerto de escucha

PUERTO=8555

BUFSIZ=1024

clase?TcpClient:

ADDR=(HOST,?PORT)

def?__init__( self):

self.HOST?=?HOST

self.PORT?=?PORT

self.BUFSIZ?=?BUFSIZ

#Crear conexión de socket

self.client?=?socket(AF_INET,?SOCK_STREAM)

self.client.connect(self.ADDR)

#Iniciar un hilo y monitorear la información recibida

self.trecv?=?threading.Thread(target=self.recvmsg)

self.trecv.start()

def?sendmsg(self):

# Enviar mensajes de chat en un bucle Si la conexión de socket existe, se repetirá para siempre. Al enviar, cierre el enlace.

while?self .client.connect_ex(self.ADDR):

data=raw_input('>:')

if?not?data:

romper

self.client.send(data.encode('utf8'))

print(u'Enviar información a %s: %s'?%(self.HOST,data ))

si

?data.upper()=="SALIR":

self.client.close()

imprimir?u"Cerrar"

romper

romper

p>

def?recvmsg(self):

#Recibir mensajes Si el enlace siempre existe, continúa escuchando para recibir mensajes.

intenta:

mientras ?self.client.connect_ex(self.ADDR):

data=self.client.recv(self.BUFSIZ)

print(recibiste información de %s: % s'?%(self.HOST,data.decode('utf8')))

except?Exception,e:

print?str(e)

if?__name__?==?'__main__':

client=TcpClient()

client.sendmsg()

Versión UDP: socket-udp -server.py

#?-*-?coding:utf8?-*-

import?sys

¿importar?tiempo

importar?traceback

importar?threading

recargar(sys)

sys.setdefaultencoding(' utf-8')

¿importar?socket

importar?traceback

HOST?=?"127.0.0.1"

PUERTO? =?9555

CHECK_PERIOD?= ?20

CHECK_TIMEOUT?=?15

clase?UdpServer(objeto):

def? __init__(self):

self .clients?=?[]

self.beats?=?{}

self.ADDR?=?(HOST ,PORT)

prueba:

self.sock?=?socket.socket(socket.AF_INET,?socket.SOCK_DGRAM)

self.sock.bind (self.ADDR)#?Vincular al mismo nombre de dominio Todas las máquinas

self.beattrs?=?threading.Thread(target=self.checkheartbeat)

self.beattrs.start ()

excepto?Excepción,e:

traceback.print_exc()

return?False

def?listen_client(self) :

¿mientras? Verdadero:

time.sleep(0.5)

imprimir?"hohohohohoo"

prueba:

recvData,dirección?=?self.sock .recvfrom(2048)

si?not?recvData:

self.close_client(dirección)

break

if?address? in?self.clients:

senddata?=?u"La información que %s me envió es: %s"?%(str(address)

,recvData.decode('utf8'))

if?recvData.upper()?==?"QUIT":

self.close_client(dirección)

if?recvData?==?"HEARTBEAT":

self.heartbeat(dirección)

continuar

si no:

self.clients.append(dirección)

senddata?=?u"El mensaje que %s me envió es: %s"?%(str(dirección),u'ingresó a la sala de chat')

para?c?in?self.clients:

pruebe:

self.sock.sendto(senddata,c)

excepto? Excepción,e:

print?str(e)

self.close_client(c)

¿excepto?Excepción,e:

#?traceback.print_exc()

print?str(e)

pasar

def?heartbeat(self,dirección):

self.beats[dirección]?=?time.time()

def?checkheartbeat(self):

mientras?True:

imprimir? checkheartbeat"

imprimir?self.beats

prueba:

para?c?in?self.clients:

imprimir? tiempo .time()

imprimir?self.beats[c]

if?self.beats[c]?+?CHECK_TIMEOUT?

print?u"%s latido se agotó y la conexión se desconectó"?%str(c)

self.close_client(c)

else:

print?u"checkp%s, sin desconexión"?%str(c)

excepto?Exception,e:

traceback.print_exc()

imprimir?str(e)

pasar

tiempo.sleep(CHECK_PERIOD)

def?close_client(self,dirección):

pruebe:

if?address?in?self.clients:

self.clients.remove(dirección)

if?self.beats. has_key(dirección):

del?self.beats[dirección]

imprimir?self.clients

para?c?in?self.clients:

self.sock.sendto(u'%s se ha ido'?%?str(dirección),c)

print(str(dirección)+u'ha salido')

excepto?Excepción,e:

print?str(e)

raise

if?__name__?==?"__main__ " :

ud

pServer?=?UdpServer()

udpServer.listen_client()

——————————Hermosa línea divisoria——————————

socket-udp-client.py:

#?-*-?coding:utf8?-*-

import?sys

importar?threading

importar?time

recargar(sys)

sys.setdefaultencoding('utf-8')

importar ?socket

HOST?=?"127.0.0.1"

PORT?=?9555

#BEAT_PORT?=?43278

BEAT_PERIOD?=?5

clase?UdpClient(objeto):

def?__init__(self):

self.clientsock?=?socket.socket ( socket.AF_INET,socket.SOCK_DGRAM)

self.HOST?=?HOST

self.ADDR?=?(HOST,PORT)

self. .sendto(u'Solicitud para establecer un enlace',self.ADDR)

self.recvtrs?=?threading.Thread(target=self.recvmsg)

self.recvtrs. start ()

self.hearttrs?=?threading.Thread(target=self.heartbeat)

self.hearttrs.start()

def?sendmsg ( self):

mientras?True:

datos?=?raw_input(">:")

si?no?datos:

romper

self.clientsock.sendto(data.encode('utf-8'),self.ADDR)

if?data.upper()?==? ' SALIR':

self.clientsock.close()

romper

def?heartbeat(self):

mientras?True :

self.clientsock.sendto('HEARTBEAT',self.ADDR)

time.sleep(BEAT_PERIOD)

def?recvmsg(self):

p>

mientras?True:

recvData,addr?=?self.clientsock.recvfrom(1024)

si?no?recvData:

break

print(u' recibió información de %s: %s'?%(self.HOST,recvData.decode('utf8')))

si?__nombre__? ==?"__main__":

udpClient?=?UdpClient()

udpClient.sendmsg()