Pythonはsocketベースの非ブロックマルチチャットルームプログラム(単一スレッド&マルチスレッド)を記述する

5037 ワード

先行知識:socket非ブロック関数(socket.setblocking(False))、単純マルチスレッドプログラミング
コードの例:
1.シングルスレッド非ブロックバージョン:
サービス:
#!/usr/bin/env python
# encoding: utf-8
import socket
import os
import sys
import time
import traceback

reload(sys)
sys.setdefaultencoding("utf-8")

def socketInit(HOST,PORT):
	s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
	s.setblocking(False)
	s.bind((HOST,PORT))
	s.listen(5)
	return s

def socketAccept(s,socketAddrList):
	try:
		sT,sTAddr = s.accept()
	except Exception as e:
		pass
	else:
		socketAddrList[sT] = sTAddr[0] + ":" + str(sTAddr[1])
		print "[*]User [%s:%s] is Online" % (sTAddr[0],str(sTAddr[1]))
		sT.send("[*]Hello,This is Server >_< ...")

def socketWorking(socketAddrList):
	for sTarg in socketAddrList.keys():
		try:
			sBuffer = sTarg.recv(2048)
		except Exception as e:
			continue
		else:
			if len(sBuffer) > 0:
				t = time.ctime()
				sBuffer = "[%s %s]%s" % (t,socketAddrList[sTarg],sBuffer)
				print sBuffer
				sTarg.send(sBuffer)
			else:
				pass


def main():
	HOST = "127.0.0.1"
	PORT = 7676
	socketAddrList = {}
	s = socketInit(HOST,PORT)
	try:
		while True:
			socketAccept(s,socketAddrList)
			socketWorking(socketAddrList)
	except KeyboardInterrupt:
		sys.exit(0)


if __name__ == '__main__':
	main()

クライアント:
#!/usr/bin/env python
# encoding: utf-8
import socket
import os
import sys
import time
import traceback

reload(sys)
sys.setdefaultencoding("utf-8")

def SocketInit():
	try:
		s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
	except Exception as e:
		print "[-]Socket Create Error"
		sys.exit(-1)
	else:
		print "[*]Socket Create Success"
	return s

def Conn(s,host,port):
	while 1:
		try:
			s.connect((host,port))
		except Exception as e:
			print "[-]Socket Connect Error"
			#traceback.print_exc()
			time.sleep(2)
			#sys.exit(-1)
		else:
			print "[*]Socket Connect Success"
			break

def main():
	host = "127.0.0.1"
	port = 7676
	sC = SocketInit()
	Conn(sC, host, port)
	print sC.recv(1024)
	try:
		while 1:
			Str_buffer = raw_input(host+":"+str(port)+">")
			try:
				sC.send(Str_buffer)
			except Exception as e:
				print "[-]Can not send Data"
			else:
				recv_buffer = sC.recv(1024)
				if not recv_buffer:
					print "[-]Server is Off"
				else:
					print recv_buffer
	except KeyboardInterrupt:
		sC.close()
		sys.exit(0)

if __name__ == '__main__':
	main()

2.マルチスレッド非ブロックバージョン
サービス:
#!/usr/bin/env python
# encoding: utf-8
import socket
import os
import sys
import time
import traceback
from threading import Thread

reload(sys)
sys.setdefaultencoding("utf-8")

def socketInit(HOST,PORT):
	s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
	s.setblocking(False)
	s.bind((HOST,PORT))
	s.listen(5)
	return s


def socketWorking(sTarg,addr):
	while True:
		try:
			sBuffer = sTarg.recv(2048)
		except Exception as e:
			pass
		else:
			if len(sBuffer) > 0:
				t = time.ctime()
				sBuffer = "[%s %s]%s" % (t,addr[0]+":"+str(addr[1]),sBuffer)
				print sBuffer
				sTarg.send(sBuffer)
			else:
				pass
		time.sleep(0.2)

def socketAccept(s,threadsList):
	try:
		sT,addr = s.accept()
	except Exception as e:
		pass
	else:
		print "[*]User [%s:%s] is Online" % (addr[0],str(addr[1]))
		sT.send("[*]Hello,This is Server >_< ...")
		t = Thread(target=socketWorking,args=(sT,addr,))
		threadsList.append(t)
		t.start()


def main():
	HOST = "127.0.0.1"
	PORT = 7676
	threadsList = []
	s = socketInit(HOST,PORT)
	try:
		while True:
			socketAccept(s,threadsList)
	except KeyboardInterrupt:
		sys.exit(0)


if __name__ == '__main__':
	main()

クライアント:
#!/usr/bin/env python
# encoding: utf-8
import socket
import os
import sys
import time
import traceback

reload(sys)
sys.setdefaultencoding("utf-8")

def SocketInit():
	try:
		s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
	except Exception as e:
		print "[-]Socket Create Error"
		sys.exit(-1)
	else:
		print "[*]Socket Create Success"
	return s

def Conn(s,host,port):
	while 1:
		try:
			s.connect((host,port))
		except Exception as e:
			print "[-]Socket Connect Error"
			#traceback.print_exc()
			time.sleep(2)
			#sys.exit(-1)
		else:
			print "[*]Socket Connect Success"
			break

def main():
	host = "127.0.0.1"
	port = 7676
	sC = SocketInit()
	Conn(sC, host, port)
	print sC.recv(1024)
	try:
		while 1:
			Str_buffer = raw_input(host+":"+str(port)+">")
			try:
				sC.send(Str_buffer)
			except Exception as e:
				print "[-]Can not send Data"
			else:
				recv_buffer = sC.recv(1024)
				if not recv_buffer:
					print "[-]Server is Off"
				else:
					print recv_buffer
	except KeyboardInterrupt:
		sC.close()
		sys.exit(0)

if __name__ == '__main__':
	main()