修改版本的多线程socket服务端
#! /usr/bin/python
import threading,socket,sys,os,time
import daemon
SERVER = "0.0.0.0"
PORT = 8888
def MyTalkThread(sock,num):
import struct
while True:
#sock.accept()是阻塞的,没有连接接入就不会继续往下走,所以不会出现在循环中不停的accpet再close()的情况——之前忘记accept是阻塞的了,导致一直以为这样写不停的开关连接...
curSock,useradd = sock.accept()
curSock.settimeout(10)
print "Thread num is",num
#第二层循环就是长连接了...前面定义超时时间settimeout,
while True:
print "11111"
#recv也是阻塞的...
getData = curSock.recv(1024)
print "222"
#定义好收包的包结构
try:
packageType,packageLong,packageData = struct.unpack('BB1022S',getData)
#包不对直接结束循环就断开了,这里以后面应该改成continue
except:
print "error package"
print len(getData),":",getData
break
#包tpye正确处理,后面还可以加其他type,比如关闭包,用户账号密码包,聊天数据包等
if packageType == 1000:
packageData = packageData[:pacakgeLong]
print num,"Thread get data",packageData
#else情况以后也可以改continue
else:
break
#之前我一直用sock.close()所以一直报错,这里其实是关闭accpet()返回的对象
curSock.close()
class TalkServer(object):
def __init__(self):
self.socket = None
def run(self):
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.bind((SERVER,PORT))
self.socket.listen(10)
thread_pool = []
for i in range(10):
TalkThread = threading.Thread(target=MyTalkThread,args=(self.socket,i))
TalkThread.start()
thread_pool.append(TalkThread)
for thread_list in thread_pool:
thread_list.join()
if __name__ == '__main__':
myas = TalkServer()
myas.run()
这个代码可以直接用telnet测试,服务器端不会发东西给客户端
这个代码有个大问题,就是curSock.settimeout(10)后,线程会死掉orz,暂时还不知道别人怎么在设置关闭curSock的。
嘿嘿又查了下timeout解决了,在curSock,useradd = sock.accept()前面加个try:做错误处理,出错直接关闭连接就ok啦
思路从下面连接找到的
这代码的缺陷在于
1、一开始创建了10个线程,于是最多只能连接10个客户端,如果客户端增加就无法连接,需要添加增加线程的代码。
2、没有线程间的通信,聊天室需要群发单个线程发来的消息到所有线程。
因此程序需要涉及到1、python线程间数据通讯 2、python线程池的实现
阅读(1510) | 评论(0) | 转发(0) |