python实现简易聊天需要登录_用Python实现一个简单的聊天程序

1 '''

2 TCP Client Version 2.23 2015.12.194 '''

5

6 importselectors7 importqueue8 importre9 importthreading10 from socket import *

11 from tkinter import *

12 from time importctime13

14 BUFSIZE = 1024

15

16 #lock = threading.Lock() # Global Lock

17 que = queue.Queue(4096)18

19 classGUI(object):20 '''

21 This is the top module. It interacts with users. When a button is clicked22 or Return is pressed, a corresbonding event trigered. Connect is used to23 estanblish a TCP connection with server while Log In tells server a user24 comes. We also provide an Add button, which allows user to add contacts.25 All the contacts will be displayed in a list box, and a double click on26 each contact will direct the user's message to a specific contact.27 Note that this module is based on other modules like Send and Recv, so it28 is not concerned with send and receive details. In fact it is wisdom to29 throw this burden to others. We just do what we can and do it perfectly.30 '''

31 def __init__(self):32 self.root =Tk()33 self.root.title('Chat')34

35 self.frame_lft =Frame(self.root)36 self.frame_rgt =Frame(self.root)37 self.frame_lft.grid(row=0, column=0)38 self.frame_rgt.grid(row=0, column=1)39

40 self.entry_msg = Entry(self.frame_lft, width=46) #entry, collect input

41 self.entry_msg.grid(row=1, column=0)42 self.entry_msg.bind('', self.send_method)43

44 self.scrollbar_txt = Scrollbar(self.frame_lft, width=1)45 self.scrollbar_txt.grid(row=0, column=2, sticky=W+N+S)46

47 #self.button_qit = Button(self.root, text='Quit', command=self.root.quit)

48 #self.button_qit.pack()

49

50 self.text_msg = Text(self.frame_lft, state=DISABLED, width=49, wrap=WORD) #text, display message

51 self.text_msg.config(font='Fixedsys')52 self.text_msg.grid(row=0, column=0, columnspan=2, sticky=W+N+S+E)53 self.text_msg.config(yscrollcommand=self.scrollbar_txt.set)54 self.scrollbar_txt.config(command=self.text_msg.yview)55

56 self.entry_IP = Entry(self.frame_rgt, width=14) #an IP address is supposed to input here

57 self.entry_IP.grid(row=0, column=0, padx=5, pady=0)58 self.entry_IP.bind('', self.connect_method)59

60 self.button_cnt = Button(self.frame_rgt, text='connect', command=self.connect_method) #click this button to connect

61 self.button_cnt.config(height=1, width=8)62 self.button_cnt.grid(row=0, column=1, padx=0, pady=0)63

64 self.button_snd = Button(self.frame_lft, height=1, text='send', command=self.send_method)65 self.button_snd.config(width=8)66 self.button_snd.grid(row=1, column=1)67

68 ## New features in version 2.2 ##

69 self.entry_log = Entry(self.frame_rgt, width=14) #log in

70 self.entry_log.grid(row=1, column=0, padx=5, pady=0)71 self.entry_log.bind('', self.login_method)72

73 self.button_log = Button(self.frame_rgt, text='log in', command=self.login_method) #first click means log in, second means log out

74 self.button_log.config(width=8)75 self.button_log.grid(row=1, column=1, sticky=W)76

77 self.listbox_cat = Listbox(self.frame_rgt, height=17, width=24)78 self.listbox_cat.insert(END, '000000')79 self.listbox_cat.grid(row=3, column=0, columnspan=2, padx=5, sticky=N+S+E)80 self.listbox_cat.bind('', self.contact_method)81

82 self.scrollbar_cat = Scrollbar(self.frame_rgt, width=1)83 self.scrollbar_cat.grid(row=3, column=2, sticky=W+N+S)84 self.scrollbar_cat.config(command=self.listbox_cat.yview)85 self.listbox_cat.config(yscrollcommand=self.scrollbar_cat.set)86

87 self.entry_add = Entry(self.frame_rgt, width=14)88 self.entry_add.grid(row=4, column=0, padx=5, pady=0)89 self.entry_add.bind('', self.add_method)90

91 self.button_add = Button(self.frame_rgt, width=8, text='add')92 self.button_add.config(command=self.add_method)93 self.button_add.grid(row=4, column=1)94

95 self.label_cat = Label(self.frame_rgt, text='Contacts')96 self.label_cat.grid(row=2, column=0, sticky=W)97

98 def send_method(self, ev=None):99 data =self.entry_msg.get()100 self.entry_msg.delete(0, END)101 if notdata:102 pass

103 else:104 self.text_msg.config(state=NORMAL)105 self.text_msg.insert(END, data+'\n')106 self.text_msg.config(state=DISABLED)107 self.text_msg.see(END)108 self.send.send(data)109

110 defrecv_method(self):111 try:112 data = que.get(block=False)113 except:114 pass

115 else:116 self.text_msg.config(state=NORMAL)117 self.text_msg.insert(END, data+'\n')118 self.text_msg.config(state=DISABLED)119 self.text_msg.see(END)120 if re.match(r'^FROME', data): #log in failed

121 self.entry_log.config(state=NORMAL)122 self.button_log.config(text='log in', command=self.login_method)123

124 self.root.after(200, self.recv_method) #runs every 200ms

125

126 def connect_method(self, ev=None):127 IP =self.entry_IP.get()128 self.connt = Connt(IP) #make an instance of Connt class

129 self.connt() #establish connection

130 self.button_cnt.config(state=DISABLED)131 self.entry_IP.config(state=DISABLED)132 self.send = Send(self.connt.tcpCliSock) #make an instance of Send class

133 self.recv = Recv(self.connt.tcpCliSock) #make an instance of Recv class

134 self.recv_thread = threading.Thread(target=self.recv) #a new thread, dealing with receiving

135 self.recv_thread.daemon =True136 self.recv_thread.start()137 self.root.after(200, self.recv_method)138

139 def login_method(self, ev=None):140 ID =self.entry_log.get()141 if re.match(r'^[0-9]{6}$', ID) ==None:142 pass

143 else:144 self.send.send(ID) #this action is infalliable

145 self.button_log.config(text='log out', command=self.logout_method)146 self.entry_log.config(state=DISABLED)147

148 def logout_method(self, ev=None):149 self.send.send('::LOG OUT')150 self.button_log.config(text='log in', command=self.login_method)151 self.entry_log.config(state=NORMAL)152

153 def contact_method(self, ev=None):154 ID =self.listbox_cat.get(self.listbox_cat.curselection())155 self.send.send('::'+ID)156 self.text_msg.delete(1.0, END) #delete all text

157 self.text_msg.config(state=NORMAL)158 self.text_msg.insert(END, '[to'+ID+' '+ctime()+']\n')159 #if this contact action fails, server will send an error message.

160

161 def add_method(self, ev=None):162 ID =self.entry_add.get()163 if re.match(r'[0-9]{6}', ID) ==None:164 pass

165 else:166 self.listbox_cat.insert(END, ID)167

168 classSend(object):169 '''

170 This module deals with every detail in sending bytes through a socket,171 such as lock, encode, blocking, etc, and provide a send interface for172 GUI module.173 '''

174 def __init__(self, fd):175 self.fd =fd176 self.sel =selectors.DefaultSelector()177 self.sel.register(self.fd, selectors.EVENT_WRITE)178

179 defsend(self, data):180 self.sel.select() #wait until the socket is ready to write

181 #if lock.acquire():

182 self.fd.send(data.encode('utf-8'))183 #lock.release()

184 #else:

185 #pass

186

187 classRecv(object):188 '''

189 This module deals with every detail in receiving bytes from a socket,190 and providing a friendly recv interface for GUI module.191 '''

192 def __init__(self, fd):193 self.fd =fd194 self.sel =selectors.DefaultSelector()195 self.sel.register(self.fd, selectors.EVENT_READ)196

197 defrecv(self):198 whileTrue:199 self.sel.select()200 #if lock.acquire():

201 byte =self.fd.recv(BUFSIZE)202 que.put(byte.decode('utf-8'))203 #lock.release()

204 #else:

205 #pass

206

207 def __call__(self):208 self.recv()209

210 classConnt(object):211 '''

212 This module deals with establishing a TCP connection with host.213 '''

214 def __init__(self, IP):215 self.HOST =IP216 self.PORT = 21567

217 self.ADDR =(self.HOST, self.PORT)218 self.tcpCliSock =socket(AF_INET, SOCK_STREAM)219

220 defconnect(self):221 self.tcpCliSock.connect(self.ADDR)222

223 def __call__(self):224 self.connect()225

226 defmain():227 gui =GUI()228 gui.root.mainloop()229

230 if __name__ == '__main__':231 main()232

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值