python socket 多人聊天室

zbaigao

python socket 多人聊天室

zbaigao 发布于 2013年10月27日 11时, 4评/747阅
分享到 
收藏 +18
0
参考来源(其实我从上面复制了一点):
Python 的 Socket 编程教程  http://www.oschina.net/question/12_76126
Python线程指南 http://www.open-open.com/lib/view/open1345476194313.html

具体思路:
每个client有两个线程,分别负责接收和发送,当没有发送时,在raw_input()那卡住,当没有接收时,在recv()那卡住
server为每个client开两个线程,分别处理接收和发送。每个发送的线程在con.wait()那阻塞,等待notify。每个接收的线程,在recv()那里等待来自client的输入,接收到输入后,发出一个notify,激活所有输出线程,自身则因为循环在下一个recv()那里等待。

这样做的优势时在等待期间,cpu都处于空闲状态,cpu只在接收和发送的瞬间被使用。
目前没有想到更好方法。。。

注意:
我做得有点粗糙,复制后有些注释和代码对应不起来,也没有添加新的注释
标签: <无>

代码片段(4)[全屏查看所有代码]

1. [文件] client.py ~ 976B     下载(23)    

# -*- coding: utf-8 -*-
"""
Created on Thu Oct 24 17:35:50 2013

@author: zbg
"""

import socket
import threading


inString = ''
outString = ''
nick = ''

def DealOut(s):
    global nick, outString
    while True:
        outString = raw_input()
        outString = nick + ': ' + outString
        s.send(outString)

def DealIn(s):
    global inString
    while True:
        try:
            inString = s.recv(1024)
            if not inString:
                break
            if outString != inString:
                print inString
        except:
            break
        

nick = raw_input("input your nickname: ")
ip = raw_input("input the server's ip adrress: ")
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((ip, 8888))
sock.send(nick)

thin = threading.Thread(target = DealIn, args = (sock,))
thin.start()
thout = threading.Thread(target = DealOut, args = (sock,))
thout.start()

#sock.close()

2. [文件] server.py ~ 2KB     下载(19)    

# -*- coding: utf-8 -*-
"""
Created on Fri Oct 25 10:33:44 2013

@author: zbg
"""
import socket
import sys
import threading

con = threading.Condition()
HOST = raw_input("input the server's ip adrress: ")	# Symbolic name meaning all available interfaces
PORT = 8888	# Arbitrary non-privileged port
data = ''

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
s.bind((HOST, PORT))
s.listen(10)
print 'Socket now listening'

#Function for handling connections. This will be used to create threads
def clientThreadIn(conn, nick):
    global data
#infinite loop so that function do not terminate and thread do not end.
    while True:
    #Receiving from client
        try:
            temp = conn.recv(1024)
            if not temp:
                conn.close()
                return
            NotifyAll(temp)
            print data
        except:
            NotifyAll(nick + " leaves the room!")
            print data
            return

	#came out of loop

def NotifyAll(sss):
    global data
    if con.acquire():
        data = sss
        con.notifyAll()
        con.release()
 
def ClientThreadOut(conn, nick):
    global data
    while True:
        if con.acquire():
            con.wait()
            if data:
                try:
                    conn.send(data)
                    con.release()
                except:
                    con.release()
                    return
                    

while 1:
    #wait to accept a connection - blocking call
    conn, addr = s.accept()
    print 'Connected with ' + addr[0] + ':' + str(addr[1])
    nick = conn.recv(1024)
     #send only takes string
    #start new thread takes 1st argument as a function name to be run, second is the tuple of arguments to the function.
    NotifyAll('Welcome ' + nick + ' to the room!')
    print data
    print str((threading.activeCount() + 1) / 2) + ' person(s)!'
    conn.send(data)
    threading.Thread(target = clientThreadIn , args = (conn, nick)).start()
    threading.Thread(target = ClientThreadOut , args = (conn, nick)).start()

s.close()

3. [图片] QQ截图20131027115134.png    

4. [图片] QQ截图20131027115232.png    

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值