Python聊天室

来源:互联网 发布:ubuntu不能创建文件夹 编辑:程序博客网 时间:2024/05/29 11:10

Python聊天室

一、套接字

    套接字是为特定网络协议(例如TCP/IP,ICMP/IP,UDP/IP等)套件对上的网络应用程序提供者提供当前可移植标准的对象。它们允许程序接受并进行连接,如发送和接受数据。为了建立通信通道,网络通信的每个端点拥有一个套接字对象极为重要。    套接字为BSD UNIX系统核心的一部分,而且他们也被许多其他类似UNIX的操作系统包括Linux所采纳。许多非BSD UNIX系统(如ms-dos,windows,os/2,mac os及大部分主机环境)都以库形式提供对套接字的支持。    三种最流行的套接字类型是:stream,datagram和raw。stream和datagram套接字可以直接与TCP协议进行接口,而raw套接字则接口到IP协议。但套接字并不限于TCP/IP。

二、套接字模块

    套接字模块是一个非常简单的基于对象的接口,它提供对低层BSD套接字样式网络的访问。使用该模块可以实现客户机和服务器套接字。要在python 中建立具有TCP和流套接字的简单服务器,需要使用socket模块。利用该模块包含的函数和类定义,可生成通过网络通信的程序。

服务器端:

step-1:        创建socket对象。调用socket构造函数。        socket=socket.socket(familly,type)        family的值可以是AF_UNIX(Unix域,用于同一台机器上的进程间通讯),也可以是AF_INET(对于IPV4协议的TCP和 UDP),至于type参数,SOCK_STREAM(流套接字)或者 SOCK_DGRAM(数据报文套接字),SOCK_RAW(raw套接字)。step-2:        将socket绑定(指派)到指定地址上。        socket.bind(address)        address必须是一个双元素元组,((host,port)),主机名或者ip地址+端口号。如果端口号正在被使用或者保留,或者主机名或ip地址错误,则引发socke.error异常。step-3:        绑定后,必须准备好套接字,以便接受连接请求。        socket.listen(backlog)        backlog指定了最多连接数,至少为1,接到连接请求后,这些请求必须排队,如果队列已满,则拒绝请求。step-4:        服务器套接字通过socket的accept方法等待客户请求一个连接。        connection,address=socket.accept()        调用accept方法时,socket会进入'waiting'(或阻塞)状态。客户请求连接时,方法建立连接并返回服务器。accept方法返回一个含有俩个元素的元组,形如(connection,address)。第一个元素(connection)是新的socket对象,服务器通过它与客户通信;第二个元素(address)是客户的internet地址。step-5:        处理阶段,服务器和客户通过send和recv方法通信(传输数据)。服务器调用send,并采用字符串形式向客户发送信息。send方法返回已发送的字符个数。服务器使用recv方法从客户接受信息。调用recv时,必须指定一个整数来控制本次调用所接受的最大数据量。recv方法在接受数据时会进入'blocket'状态,最后返回一个字符串,用它来表示收到的数据。如果发送的量超过recv所允许,数据会被截断。多余的数据将缓冲于接受端。以后调用recv时,多余的数据会从缓冲区删除。step-6:        传输结束,服务器调用socket的close方法以关闭连接。

客户端:

step-1:        创建一个socket以连接服务器。        socket=socket.socket(family,type)step-2:        使用socket的connect方法连接服务。        socket.connect((host,port))step-3:        客户和服务器通过send和recv方法通信。step-4:        结束后,客户通过调用socket的close方法来关闭连接。

server.py

    if __name__ == '__main__':        import socket        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)        sock.bind(("XXX.XXX.XXX.X", XXXX))        sock.listen(5)        connection,address = sock.accept()        data = connection.recv(1024)        print data        if data == '1\'m on your own side.':            connection.send('welcome!')        else:            connection.send('gun!')        connection.close()

client.py

    if __name__ == '__main__':        import socket        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)        sock.connect(("XXX.XXX.XXX.X", XXXX))        key=raw_input("join us or not? y/n. ")        if key is "y":            sock.send('1\'m on your own side.')        if key is "n":            sock.send('fuck you all!')            print sock.recv(1024)        sock.close()
    这是一个简单网络编程。    在终端运行server.py,然后运行clien.py,会在终端打印“join us or not? y/n."。如果客户端输入"y",则服务器端会收到"1'm on your own side."。如果客户端输入"n",则服务器端会收到"fuck you all!",然后服务器端会回敬一句"gun!"。

serverplus.py

    import socket,select,thread;    host=socket.gethostname()    port=5963    addr=(host,port)    inputs=[]    fd_name={}    def main():        print 'runing'        ss=socket.socket()        ss.bind(addr)        ss.listen(5)        inputs.append(ss)        while True:            r,w,e=select.select(inputs,[],[])            for temp in r:                if temp is ss:                      client,add=ss.accept()                    print 'welcome %s %s' % (client,add)                    wel='''welcome into the talking room . please decide your name.....'''                    try:                        client.send(wel)                        name=client.recv(1024)                        inputs.append(client)                        fd_name[client]=name                        for client in fd_name:                            fd_name.append(fd_name[client])                        nameList="Some people in talking room, these are %s" % (fd_name)                        client.send(nameList)                        except Exception,e:                        print e                            else:                    disconnect=False                    try:                        data= temp.recv(1024)                        data=fd_name[temp]+' say : '+data                    except socket.error:                        data=fd_name[temp]+' leave the room'                        disconnect=True                                        if disconnect:                        inputs.remove(temp)                        print data                        for other in inputs:                            if other!=ss and other!=temp:                                try:                                    other.send(data)                                except Exception,e:                                    print e                                            del fd_name[temp]                                       else:                        print data                                          for other in inputs:                            if other!=ss and other!=temp:                                try:                                    other.send(data)                                except Exception,e:                                    print e    if __name__=='__main__':        main()            

clientplus.py

    import socket,select,threading,sys;    host=socket.gethostname()    addr=(host,5963)    def lis(s):        my=[s]        while True:            r,w,e=select.select(my,[],[])            if s in r:                try:                    print s.recv(1024)                except socket.error:                    print 'socket is error'                    exit()    def talk(s):        while True:            try:                info=raw_input()            except Exception,e:                print 'can\'t input'                exit()            try:                s.send(info)            except Exception,e:                print e                exit()    def main():        ss=socket.socket()        ss.connect(addr)        t=threading.Thread(target=lis,args=(ss,))        t.start()        t1=threading.Thread(target=talk,args=(ss,))        t1.start()    if __name__=='__main__':        main()
    这是一个终端聊天室,加入了多线程运行和异常处理。

chatroom.py

    import wx,socket,select,thread,Queue,sys    class chatdlg(wx.Dialog):        #initUI        def __init__(self):              wx.Dialog.__init__(self,None,-1,"chat room",size=(400,400))              wx.StaticText(self,-1,"IP",pos=(10,14))              self.IPText = wx.TextCtrl(self,-1,"",pos=(30,10),size=(104,25))              wx.StaticText(self,-1,"Port",pos=(144,14))  ;            self.PortText = wx.TextCtrl(self,-1,"",pos=(180,10),size=(46,25))            wx.StaticText(self,-1,"Nickname",pos=(236,14))              self.NicknameText = wx.TextCtrl(self,-1,"*Anonym",pos=(304,10),size=(80,25))              self.cButton = wx.Button(self,-1,"Client",pos=(10,45),size=(185,50))              self.Bind(wx.EVT_BUTTON,self.OnClientClick,self.cButton)              self.sButton = wx.Button(self,-1,"Server",pos=(200,45),size=(185,50))              self.Bind(wx.EVT_BUTTON,self.OnSeverClick,self.sButton)              self.DisplayText = wx.TextCtrl(self,-1,"",pos=(10,104),size=(373,198),style=wx.TE_MULTILINE)              self.InputText = wx.TextCtrl(self,-1,"",pos=(10,312),size=(263,50),style=wx.TE_MULTILINE)              self.sendButton = wx.Button(self,-1,"Send",pos=(283,312),size=(100,50))              self.Bind(wx.EVT_BUTTON,self.OnSendClick,self.sendButton)              self.sendButton.SetDefault()          #SendButoon        def OnSendClick(self,event):             #self.sendButton.SetLabel("Clicked")              self.send_data = self.InputText.GetValue()              self.nick_name = self.NicknameText.GetValue()            try:                  self.client.send(self.nick_name+" said: "+self.send_data+"\n")                  self.DisplayText.AppendText(self.nick_name+" said: "+self.send_data+"\n")                self.InputText.SetValue("")            except  socket.error,e:                  print "could not connect to chat server @%s:%d\n" % (self.host,self.port)                  return          #ServerButoon        def OnSeverClick(self,event):              self.socketmode=1              thread.start_new_thread(self.SocketProc_server,())          #ClientButton        def OnClientClick(self,event):              self.socketmode=0              #self.cButton.SetLabel("connected")              thread.start_new_thread(self.SocketProc_client,())          #Server        def SocketProc_server(self):                # Sockets to which we expect to write              outputs = [ ]              # Outgoing message queues (socket:Queue)              message_queues = {}              self.server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)              self.port = int(self.PortText.GetValue())              self.host = ""              print "waiting for connection @%s:%d\n" % (self.host,self.port)              self.server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)              self.server.bind((self.host,self.port))              self.server.listen(10)                      self.DisplayText.AppendText("waiting for connection @%s:%d\n" % (self.host,self.port))              # Sockets from which we expect to read              inputs = [ self.server ]              while inputs:                  # Wait for at least one of the sockets to be ready for processing                  print >>sys.stderr,"waiting for the next event\n"                  readable,writable,exceptional = select.select(inputs,outputs,inputs)                  # Handle inputs                  for s in readable:                      if s is self.server:                          # A "readable" server socket is ready to accept a connection                          connection,client_address = s.accept()                          print >>sys.stderr,"new connection from",client_address                          self.DisplayText.AppendText("new connection from @%s:%s\n" % client_address)                          connection.setblocking(False)                          inputs.append(connection)                          # Give the connection a queue for data we want to send                          message_queues[connection] = Queue.Queue()                      else:                          data = s.recv(1024)                          if data:                              # A readable client socket has data                              print >>sys.stderr,"@%s:%s" % (s.getpeername(),data)                              self.DisplayText.AppendText("@%s:%s" % (s.getpeername(),data))                              for c in inputs:                                  if c is self.server:                                      print >>sys.stderr,"from server"                                  elif c is not s:                                      print >>sys.stderr,"send_data [%s] to %s" % (data,s.getpeername())                                      message_queues[c].put(data)                                      if c not in outputs:                                          outputs.append(c)                          else:                              # Interpret empty result as closed connection                              print >>sys.stderr,"closing",client_address,"after reading no data"                              self.DisplayText.AppendText("closing @%s:%s after reading no data\n\n" % client_address)                              # Stop listening for input on the connection                              if s in outputs:                                  outputs.remove(s)                              inputs.remove(s)                              s.close()                              # Remove message queue                              del message_queues[s]                  # Handle outputs                  for s in writable:                      try:                          next_msg = message_queues[s].get_nowait()                      except Queue.Empty:                          # No messages waiting so stop checking for writability.                          print >>sys.stderr,"output queue for",s.getpeername(),"is empty"                          outputs.remove(s)                      else:                          print >>sys.stderr,'sending "%s" to %s' % (next_msg,s.getpeername())                          s.send(next_msg)                  # Handle "exceptional conditions"                  for s in exceptional:                      print >>sys.stderr,"handling exceptional condition for",s.getpeername()                      self.DisplayText.AppendText("handling exceptional condition for",s.getpeername())                      # Stop listening for input on the connection                      inputs.remove(s)                      if s in outputs:                          outputs.remove(s)                      s.close()                      # Remove message queue                      del message_queues[s]             #Client        def SocketProc_client(self):              # Sockets to which we expect to write              outputs = [ ]              # Outgoing message queues (socket:Queue)              message_queues = {}              self.client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)              self.host = str(self.IPText.GetValue())              self.port = int(self.PortText.GetValue())              print "Connecting to chat server@%s:%d\n" % (self.host,self.port)              try:                  self.client.connect((self.host,self.port))                  print "connected to chat server @%s:%d\n" % (self.host,self.port)              except socket.error,e:                  print "Could not connect to chat server @%s:%d\n" % (self.host,self.port)                  return              inputs = [ self.client ]              message_queues[self.client] = Queue.Queue()              while inputs:                  # Wait for at least one of the sockets to be ready for processing                  print >>sys.stderr,"\nwaiting for the next event"                  readable,writable,exceptional = select.select(inputs,outputs,inputs)                  # Handle inputs                  for s in readable:                      data = s.recv(1024)                      if data:                          # A readable client socket has data                          print >>sys.stderr,'received "%s" from %s' % (data,s.getpeername())                          self.DisplayText.AppendText(data)                      else:                          # Interpret empty result as closed connection                          print >>sys.stderr,"closing",client_address,"after reading no data"                          self.DisplayText.AppendText("closing @%s:%s after reading no data\n\n" % client_address)                          # Stop listening for input on the connection                          if s in outputs:                              outputs.remove(s)                          inputs.remove(s)                          s.close()                          # Remove message queue                          del message_queues[s]                  # Handle outputs                  for s in writable:                      try:                          next_msg = message_queues[s].get_nowait()                      except Queue.Empty:                          # No messages waiting so stop checking for writability.                          print >>sys.stderr,"output queue for",s.getpeername(),"is empty"                          outputs.remove(s)                      else:                          print >>sys.stderr,'sending "%s" to %s' % (next_msg,s.getpeername())                          s.send(next_msg)                  # Handle "exceptional conditions"                  for s in exceptional:                      print >>sys.stderr,"handling exceptional condition for",s.getpeername()                      self.DisplayText.AppendText("handling exceptional condition for",s.getpeername())                      # Stop listening for input on the connection                      inputs.remove(s)                      if s in outputs:                          outputs.remove(s)                      s.close()                      # Remove message queue                      del message_queues[s]              def SocketProc_process(self):              pass              #recv all recv_data              #broadcast msg      if __name__ == "__main__":          app = wx.PySimpleApp()          app.MainLoop()           dialog = chatdlg()          result = dialog.ShowModal()          if result == wx.ID_OK:              print "OK"          else:              print "Cancel"          dialog.Destroy() 
    这是一个图形聊天室,加入了图形界面。    //如果有用,那么本文是lancer写的    //如果没用,那么我也不知道是谁写的
0 0
原创粉丝点击