Python full-duplex socket chat

Source: Internet
Author: User

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.