python 实战之模仿开发QQ聊天软件(四)多用户多线程的服务器搭建

这三天时间基本上花在多线程上,但是效果好像还是不是特别好,怎么说呢,学校的老师再讲操作系统的时候我基本在睡觉,现在做这个确实比较难了。

学编程最重要的是心法,所以今天的开篇先说一点这半个月来的感受吧:

总的来说,自己比较急功近利吧,透支身体在做这个,因为之前是没有接触过python,也没有接触过项目开发。所以自己也是摸索着前进。

一、 劳逸结合。

过于求成可能适得其反!   举个例子吧,我前一段时间把qq的所有界面和个人界面的自动化做好了,于是想着要不自己打包一下程序看看能不能就光界面的运行一下,结果打包的过程中破坏了我的配置环境,于是改了两天的bug和error重新安装了环境才终于恢复到原来的工作环境。

在一个就是我这几天学这个多用户多线程这东西,真的很难吃透,就一直在搞这个,搞得脑壳儿疼!

二、 睡眠有保证。

有个清醒的头脑,逻辑才能理清楚。我这半个月的时间大部分可能都在混混沌沌的度过,思路不太清晰,效率看着挺高,一步一步的突破,但是实际上很低,都是硬拿身体拼出来的。

三、学会暂时放一放

都是初学者,遇到自己的只是技术的瓶颈很正常的,某个地方很长时间没有攻克下来,就先放一放,反正这么大的一个项目,总有一些不太需要自己动脑子的地方,先做那一部分,或者出去透透风,可能回来就有灵感怎么写了。

 

进入正题

服务器的主要功能有两个:

一、接受从客户端发来的消息

二、转发消息到目标客户端

接收信息是新用户接入服务器时,就开始做的工作,一直工作到用户断开服务器。

转发信息是只要接收到信息,就加入到队列中,只要队列中有需要发送的信息,就索引id寻找套接字。如果有对应id的套接字就发送,否则将取出的对首元素重新加入队尾。

于是主线程创建两个子线程,线程一用于发送信息,线程二用于等待新用户接入服务器。一旦用户接入立马创建接收信息的孙线程三,线程三如果没有接收到信息,就进行io堵塞,等待输入。如果收到信息就将信息放入线程一的消息队列中并唤醒线程一发送信息。线程一的消息队列如果为空,则阻塞,否则发送信息。

这里用到了一个设计模式——生产者消费者模式(producer-custom)后面会单独写一篇关于二十一种设计模式的介绍。

# -*-coding:utf-8-*
import socket
import threading
import Queue
import time

con = threading.Condition()
clients ={}
q =Queue.Queue()

def recv_msg(new_socket):
    while True:
        con.acquire()
        id = new_socket.recv(1024)
        print "id : {}".format(str(id))
        if id =="":
            new_socket.close()
            con.release()
            return
        msg = new_socket.recv(1024)
        print "received id {} and msg {}...\n".format(str(id),str(msg))
        q.put((id,msg))
        con.notifyAll()
        con.release()


def usrIn():
    tcp_server_socekt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    tcp_server_socekt.bind(("", 8888))
    tcp_server_socekt.listen(128)
    while True:
        print" waiting for connecting...."
        new_socket, addr = tcp_server_socekt.accept()
        print "...connected from : %s" % str(addr)
        usr_id = new_socket.recv(1024)
        print"The userid is ", usr_id
        clients[usr_id] = new_socket
        print"clients{}".format(clients[usr_id])
        recv = threading.Thread(target=recv_msg,args=(new_socket,))
        recv.start()
    tcp_server_socekt.close()


def send_msg():
    con.acquire()
    while q.empty():
        print"queue is empty...\n"
        con.wait()
    while q.qsize():
        print "get from queue...\n"
        tmp = q.get()
        if clients.has_key(tmp[0]):
            print"id is active...\n"
            clients[tmp[0]].send(tmp[1])
            print "send successful...\n"
        else:
            q.put(tmp)
    con.release()
    time.sleep(1)


def main():
    UI = threading.Thread(target=usrIn)
    UI.start()
    SM = threading.Thread(target=send_msg)
    SM.start()



if __name__ == '__main__':
    main()


这是python项目开发的最后一片博文。由于python更多的是用在网络爬虫大数据处理方面,所以软件开发先告一段落。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值