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
- Python聊天室
- Python聊天室
- Python聊天室程序---基础
- Python聊天室程序----界面设计
- Python聊天室程序-----美化
- Python socket聊天室程序
- Python socket聊天室程序
- 小小聊天室 Python实现
- Python实现简单聊天室
- Python +redis 聊天室
- python socket 多人聊天室
- python socket多人聊天室
- 聊天室
- 聊天室
- 聊天室
- 聊天室
- 聊天室
- 聊天室
- 黑马程序员——java集合框架
- C学习笔记(五)字符输入\输出
- 整型变量
- MySQL XML解析及數組處理
- sqlalchemy数据库连接池错误
- Python聊天室
- Linux 常用命令
- Linux设备模型之tty驱动架构分析
- 欢迎使用CSDN-markdown编辑器
- ifconfig命令
- gdb学习小结
- 关于客户端缓存网页
- linux下使用autotools创建makefile文件
- Linux下memcache的安装和启动(很好)