Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1125702
  • 博文数量: 170
  • 博客积分: 1603
  • 博客等级: 上尉
  • 技术积分: 1897
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-09 15:54
文章分类

全部博文(170)

文章存档

2016年(27)

2015年(21)

2014年(27)

2013年(21)

2012年(7)

2011年(67)

我的朋友

分类: Python/Ruby

2011-04-21 15:36:06

修改版本的多线程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) |
给主人留下些什么吧!~~