Self-learning python for some time, always want to get an interesting thing, so take the socket to do a chat room, can one-to-many, single-to full-duplex chat. The following may be perfect code in play anything a GUI interface, compared with forcing lattice 650) this.width=650; "src=" Http://img.baidu.com/hi/jx2/j_0061.gif "alt=" J_0061.gif " Style= "Padding:0px;margin:0px;vertical-align:top;border:none;"/>.
Service side:
Using the Socketserver module, multithreading asynchronously processes client messages, accepts customer messages, and forwards both service-side as a broker.
Joined the login registration multiplayer chat one-to chat to prevent simultaneous online
Client:
The main thread connects to the server, and two sub-threads are responsible for both reading and writing
Sercer:
# _*_ Coding:utf-8 _*_
Import Socketserver
From time import CTime
Import threading, Traceback
Import Queue
From DB Import db
Lock = Threading. Lock ()
Local_school = Threading.local ()
Class Handler (object):
Queue = []
db = db ()
user_name = {}
def __init__ (self, sock):
Self.sock = Sock
Self.input = [Self.sock]
# self.queue.append (Self.sock)
def recv (self):
data = SELF.SOCK.RECV (1024x768). Strip ()
Return data
def send (self, data):
Self.sock.sendall (data)
def stop (self):
Self.send (' Byebye ')
Self.sock.close ()
Self.queue.remove (Self.sock)
Del Self.user_name[local_school.user]
def exit (self):
Self.sock.close ()
Try
Self.queue.remove (Self.sock)
Del Self.user_name[local_school.user]
Except ValueError:
Pass
Def broadcast (self, user, data):
For sock in Self.queue:
Sock.sendall (' [%s]%s::%s '% (CTime (), user, data))
def one (self, user_sock, user, data):
Self.user_name[user_sock].sendall ('--------------\n%s\n[%s]::(%s) \ n---------------'% (CTime (), user, data))
def yiduiduo (self, user, data):
Time_data = CTime ()
For sock in [x to X in Self.queue if x! = Self.sock]:
Sock.sendall ('----------------\n%s\n[%s]::(%s) \ n----------------'% (time_data, user, data))
def handler (self):
Funcdict = {
' Login ': Self.login,
' Registered ': self.registered,
}
Try: # # #异常处理 When the client is abnormally disconnected or disconnected properly: server handling exception
Self.sock.send (' Please select:: Login/registered/exit ')
data = SELF.RECV ()
if data = = ' exit ':
Self.stop ()
# self.send (' exit ')
Elif Data in Funcdict:
Funcdict[data] ()
Else
Self.handler ()
Except
If Self.queue:
Self.exit ()
Else
Pass
def login (self):
Self.send (' Input account password format: User Passwd/server ')
data = SELF.RECV ()
if data = = ' Server ':
Self.send (' Select Exit/handler ')
data = SELF.RECV ()
if data = = ' exit ':
Self.stop ()
elif data = = ' Handler ':
Self.handler ()
Else
Self.login ()
User_data = Data.split ()
If Len (user_data) = = 2:
user = User_data[0]
passwd = user_data[1]
User_data = Self.db.get_data () or {}
Data_scok = self.user_name.get (user) # detects if the user is logged in or has landed in the login sock
If Data_scok:
Try
Data_scok.sendall (' Account is landed elsewhere, forced offline ')
Data_scok.close ()
Self.queue.remove (Data_scok)
Del Self.user_name[local_school.user]
Except: # #异常处理 capture all exceptions here do not handle
Pass
If user in User_data and user_data[user] = = passwd:
Local_school.user = user
Self.send (' Welcome to chat room ')
Self.queue.append (Self.sock)
Self.broadcast (' Systemctl ', ' [%s] added to chat room \ n '% user)
Self.user_name[user] = self.sock # #用户--sock Map
Self.send (' Select: Single (d)/multi (s) ')
data = SELF.RECV ()
if data = = ' s ':
Self. Ltian ()
elif data = = ' d ':
Self.one_to_one ()
Else
Self.send (' ERROR \ n ')
Self.handler ()
Else
Self.send (' Incorrect account or password!\n ')
Self.login ()
Else
Self.send (' Format error!\n ')
Self.login ()
def registered (self):
Self.send (' Registered account password-format user passwd/server ')
data = SELF.RECV ()
if data = = ' Server ':
Self.send (' Select Exit/handler ')
data = SELF.RECV ()
if data = = ' exit ':
Self.stop ()
Self.send (' exit ')
Else
Self.handler ()
User_data = Data.split ()
If Len (user_data) = = 2:
user = User_data[0]
passwd = user_data[1]
Db_data = Self.db.get_data () or {}
If user in Db_data:
Self.send (' User already registered! ‘)
Self.registered ()
Else
Db_data[user] = passwd
Local_school.user = user
Lock.acquire () # Add a thread lock to prevent threads from modifying data files at the same time
Try
Self.db.put_data (Db_data)
Finally
Lock.release ()
Self.queue.append (Self.sock)
Self.broadcast (' System ', ' [%s] added to chat room \ n '% user)
Self.user_name[user] = Self.sock
Self.send (' Select: Single chat (d)/multiplayer chat (s) \ n ')
data = SELF.RECV ()
if data = = ' s ':
Self. Ltian ()
Print Self.queue
elif data = = ' d ':
Self.one_to_one ()
Else
Self.send (' Error! \ n ')
Self.handler ()
Else
Self.send (' format error \ n \ nthe ')
Self.registered ()
def Ltian (self,): # Multi-person Chat
Print Self.queue
Print Self.user_name
Self.send (' Kaishiliaotian ')
While True:
data = SELF.RECV ()
if data = = ' exit ':
print ' Queue1::%s '% Self.queue
Self.stop ()
# self.send (' Off ++++++++ ')
print ' Queue2::%s '% Self.queue
Break
Self.yiduiduo (Local_school.user, data) # Multicast message
def one_to_one (self):
Self.send (' Select object: To:user ')
User_data = Self.recv () [3:]
if User_data = = Local_school.user:
Self.one_to_one ()
If User_data in Self.db.get_data ():
If Self.user_name.get (User_data) and Self.user_name[user_data] in Self.queue:
Self.send (' Kaishiliaotian ')
While True:
data = SELF.RECV ()
# If data is None:
if data = = ' Server ':
Self.send (' Select: Exit/ltian (s) ')
data = SELF.RECV ()
if data = = ' exit ':
Self.one (User_data, Local_school.user, ' already offline ')
Self.stop ()
Break
elif data = = ' s ':
Self. Ltian ()
elif not data = = "and Self.user_name.get (User_data): # Determine data is not empty and user status online no
Self.one (User_data, Local_school.user, data)
Else
Self.send (' User not online ')
Self.one_to_one ()
Else
Self.send (' user does not exist! \ n ')
Self.one_to_one ()
Class MyServer (Socketserver.baserequesthandler):
def handle (self):
Print Self.client_address
Self.mysock = Handler (self.request)
Print Self.mysock.queue
Self.mysock.handler ()
if __name__ = = ' __main__ ':
Host = ' 127.0.0.1 '
Port = 9999
Addr = (host, port)
Server = Socketserver.threadingtcpserver (addr, MyServer)
Server.request_queue_size = 4399
Server.serve_forever ()
Server.shutdown ()
Client
# _*_ Coding:utf-8 _*_
From socket Import *
Import threading
Threads=[]
Class Client_handler (object):
def __init__ (self, ipadr= ' 127.0.0.1 ', port=9999):
Self.sock = socket (af_inet, SOCK_STREAM)
Self.sock.connect ((Ipadr, Port))
Self.input=[self.sock]
Print Self.input
def send (Self,data):
Self.sock.sendall (data)
def recv (self):
data = SELF.SOCK.RECV (1024x768). Strip ()
Print data
Return data
def write (self):
While True:
Try
Data=raw_input (' >>> ')
If data== ' exit ':
Self.send (' exit ')
Self.sock.close ()
Break
Self.send (data)
Except Socket.error: #加入异常处理 jump out while loop when the server disconnects sock connection
Break
Except
Break
def read (self):
While True:
Try
SELF.RECV ()
Except Socket.error:
Break
Except
Break
A1=client_handler ()
Chat = Threading. Thread (Target=a1.write)
Threads.append (Chat)
Chat = Threading. Thread (Target=a1.read)
Threads.append (Chat)
Print Threads
For I in range (len (threads)):
Threads[i].start ()
This article is from the "13275081" blog, please be sure to keep this source http://13285081.blog.51cto.com/13275081/1964230
Python full-duplex socket chat