首页 > 代码库 > 【Python】iichats —— 命令行下的局域网聊天程序
【Python】iichats —— 命令行下的局域网聊天程序
转载请声明出处:http://www.cnblogs.com/kevince/p/3941728.html ——By Kevince
ii系列工具第三弹,命令行下的局域网聊天程序
原理:
程序启动时向全网(255.255.255.255)BACKPORT端口广播自己的主机名以及状态(上线)。
如果接受收到的上线状态,则将其加入通信列表,同时返还一个数据包,使自己也将对面加入其通信列表。
程序退出时向全网广播自己的下线状态,如果收到该下线状态则将其从自己的通信列表中删除
为了防止在输入过程中被新输出的消息打断,可以用readlines中的get_line_buffer函数获取缓冲区内的字符并储存,清空原先行,输出新结果,并在下面输出刚刚输入的内容(可用curses改进,to be continued...)
缺陷:
使用UDP协议,未添加消息到达确认机制;
跨平台支持需要修改代码(readlines只支持linux, windows下要用pyreadline,MAC OS要用edlitline来代替)
实用性不强,功能单一,学习程序
未能实现GUI图形界面的开发(目前还木有学会……)
刚学Python没多久 且开发仓促,有Bug还请多多指教~
1 #!/usr/bin/python 2 #coding:utf8 3 4 import threading 5 import socket 6 import time 7 import os 8 import sys 9 import signal 10 from readline import get_line_buffer 11 BUFSIZE = 1024 12 BACKPORT = 7789 #状态监听端口 13 CHATPORT = 7788 #聊天信息发送窗口 14 START = ‘>>‘ 15 INIT = ‘>>‘ 16 users = {} 17 ips = {} 18 #起到双向字典的作用,ip和name互相映射 19 20 #数据处理类(消息封装、分解) 21 class Data(): 22 def gettime(self): 23 return time.strftime(‘%Y-%m-%d %H:%M‘, time.localtime(time.time())) 24 def getip(self): 25 ip = os.popen("/sbin/ifconfig | grep ‘inet addr‘ | awk ‘{print $2}‘").read() 26 ip = ip[ip.find(‘:‘)+1:ip.find(‘\n‘)] 27 return ip 28 def handlebc(self, data): 29 data = http://www.mamicode.com/data[5:] 30 res = data.split(‘#opt:‘) 31 return res 32 def makebc(self, name, switch): 33 data = http://www.mamicode.com/‘name:%s#opt:%d‘ % (name, switch) 34 return data 35 def handlechat(self, data): 36 msg = ‘\n‘ + self.gettime() + ‘\n‘ +‘from ‘+ data + ‘\n‘ 37 return msg 38 def makechat(self, data, name): 39 return name + ‘:‘ + data 40 41 #后台监听类 42 class Back(threading.Thread): 43 def __init__(self): 44 threading.Thread.__init__(self) 45 self.data =http://www.mamicode.com/ Data() 46 self.addrb = (‘255.255.255.255‘, BACKPORT) 47 self.addrl = (‘‘, BACKPORT) 48 self.name = socket.gethostname() 49 self.ip = self.data.getip() 50 self.thread_stop = False 51 def status(self, name, switch): 52 if switch == 0: 53 status = ‘offline‘ 54 elif switch == 1: 55 status = ‘online‘ 56 #用来处理输入过程中被线程返回消息打乱的情况 57 if outmutex.acquire(1): 58 sys.stdout.write(‘\r‘+‘ ‘*(len(get_line_buffer())+len(START))+‘\r‘) 59 print ‘[status] ‘+name+‘ ‘+status 60 sys.stdout.write(START+get_line_buffer()) 61 sys.stdout.flush() 62 outmutex.release() 63 def broadcast(self, switch): 64 bsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 65 bsock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) 66 data =http://www.mamicode.com/ self.data.makebc(self.name, switch) 67 bsock.sendto(data, self.addrb) 68 bsock.close() 69 def response(self, addr, switch): 70 rsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 71 data =http://www.mamicode.com/ self.data.makebc(self.name, switch) 72 rsock.sendto(data, (addr, BACKPORT)) 73 rsock.close() 74 def check(self): 75 if usermutex.acquire(): 76 ips.clear() 77 users.clear() 78 usermutex.release() 79 self.broadcast(1) 80 def run(self): 81 lsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 82 lsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 83 lsock.bind(self.addrl) 84 self.broadcast(1) 85 while not self.thread_stop: 86 data, addr = lsock.recvfrom(BUFSIZE) 87 datalist = self.data.handlebc(data) 88 if usermutex.acquire(1): 89 if datalist[1] == ‘0‘: 90 if ips.has_key(addr[0]): 91 if anoun == 1: 92 self.status(datalist[0], 0) 93 del ips[addr[0]] 94 del users[datalist[0]] 95 elif datalist[1] == ‘1‘: 96 if anoun == 1 and datalist[0] != self.name: 97 self.status(datalist[0], 1) 98 users[datalist[0]] = addr[0] 99 ips[addr[0]] = datalist[0]100 self.response(addr[0], 2)101 elif datalist[1] == ‘2‘:102 if anoun == 1 and datalist[0] != self.name:103 self.status(datalist[0], 1)104 users[datalist[0]] = addr[0]105 ips[addr[0]] = datalist[0]106 usermutex.release()107 lsock.close()108 def stop(self):109 self.broadcast(0)110 self.thread_stop = True111 112 #聊天类113 class Listen(threading.Thread):114 def __init__(self):115 threading.Thread.__init__(self)116 self.addr = (‘‘, CHATPORT)117 self.name = socket.getfqdn(socket.gethostname())118 self.data =http://www.mamicode.com/ Data()119 self.thread_stop = False120 def ans(self, addr):#to be added 用来确认消息报的接受121 return122 def run(self):123 lsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)124 lsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)125 lsock.bind(self.addr)126 while not self.thread_stop:127 data, addr = lsock.recvfrom(BUFSIZE)128 msg = self.data.handlechat(data)129 if outmutex.acquire(1):130 sys.stdout.write(‘\r‘+‘ ‘*(len(get_line_buffer())+len(START))+‘\r‘)131 print msg132 sys.stdout.write(START+get_line_buffer())133 sys.stdout.flush()134 outmutex.release()135 lsock.close()136 def stop(self):137 self.thread_stop = True138 139 #启动入口类140 class Start(): 141 def __init__(self):142 self.name = socket.getfqdn(socket.gethostname())143 self.data =http://www.mamicode.com/ Data()144 self.listen = Listen()145 self.back = Back()146 print ‘******* iichats ********‘147 print ‘ Written by Kevince \n‘148 print ‘This is ‘ + self.name149 print self.data.gettime()+‘\n‘150 #帮助信息151 def helpinfo(self): 152 if outmutex.acquire(1):153 print "use ‘:‘ to use options"154 print "\t:exit\t\t\texit iichats"155 print "\t:list\t\t\tlist online users"156 print "\t:quit\t\t\tquit the chat mode"157 print "\t:chat [hostname]\tchatting to someone"158 print "\t:set status [on|off]\tturn on/of status alarms"159 outmutex.release()160 def refresh(self):161 if outmutex.acquire(1):162 print ‘\n******Onlinelist******‘163 for key in users:164 print key165 print ‘**********************\n‘166 outmutex.release()167 def chatting(self):168 csock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)169 if outmutex.acquire(1):170 print "use ‘:help‘ to get help information"171 outmutex.release()172 name = ‘‘173 address = ‘‘174 global anoun175 global START176 while True:177 arg = raw_input(START)178 if arg[0:5] == ‘:quit‘ and START != INIT:179 name = ‘‘180 address = ‘‘181 START = INIT182 elif arg[0] == ‘:‘ and START == INIT:183 if arg[1:] == ‘exit‘:184 break185 elif arg[1:5] == ‘list‘:186 self.refresh()187 continue188 elif arg[1:12] == ‘set status ‘:189 if arg[12:] == ‘on‘:190 anoun = 1191 elif arg[12:] == ‘off‘:192 anoun = 0193 continue194 elif arg[1:5] == ‘help‘:195 self.helpinfo()196 continue197 elif arg[1:6] == ‘check‘:198 self.back.check()199 print ‘checking the list...‘200 time.sleep(3)201 if outmutex.acquire(1):202 outmutex.release()203 self.refresh()204 elif arg[1:6] == ‘chat ‘:205 name = arg[6:]206 if usermutex.acquire(1):207 userlist = users.keys()208 usermutex.release()209 if name not in userlist:210 if outmutex.acquire(1):211 print ‘this host does not exist‘212 outmutex.release()213 continue214 address = (users.get(name), CHATPORT)215 if outmutex.acquire(1):216 print ‘now chatting to ‘ + name+" ,use ‘:quit‘ to quit CHAT mode"217 START = name + INIT218 outmutex.release()219 else:220 if outmutex.acquire(1):221 print "invalid input, use ‘:help‘ to get some info"222 outmutex.release()223 else:224 if not len(address):225 if outmutex.acquire(1):226 print "you can CHAT to someone, or use ‘:help‘"227 outmutex.release()228 continue229 data =http://www.mamicode.com/ arg230 msg = self.data.makechat(data, self.name)231 csock.sendto(msg, address)232 csock.close()233 def start(self):234 self.back.setDaemon(True)235 self.back.start()236 self.listen.setDaemon(True)237 self.listen.start()238 self.chatting()239 self.back.stop()240 self.listen.stop()241 sys.exit()242 243 usermutex = threading.Lock()244 outmutex = threading.Lock()245 #控制status on和off的情况246 anoun = 1247 s = Start()248 s.start()
【Python】iichats —— 命令行下的局域网聊天程序
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。