python之聊天室

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

client.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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: ")
HOST = raw_input("input the server's host address: ")
PORT = 6666
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST,PORT))
sock.send(nick)

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

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

server.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import socket
import sys
import threading

con = threading.Condition()
HOST = raw_input("input the server's host address: ")
PORT = 6666
data = ''

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

def clientThreadIn(conn, nick):
global data
while True:
try:
temp = conn.recv(1024)
if not temp:
conn.close()
return
NotifyAll(temp)
print data
except:
NotifyAll(nick + " leaves the room !")
print data
return

def NotifyAll(sss):
global data
if con.acquire():
data = sss
con.notifyAll()
con.release()
#print data

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:
conn, addr = s.accept()
print 'connected with ' + addr[0] + ' : ' + str(addr[1])
nick = conn.recv(1024)
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()

借鉴于这里