1、ChatService.py
#!C:/Python27
#coding=utf-8
import socket
import threading
HOST = "localhost"
PORT = 6666
ADDR = (HOST, PORT)
srv_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
srv_sock.bind((HOST,PORT))
srv_sock.listen(5)#监听连接 满了挂起 5
print "\nlisting..."
con = threading.Condition()#判断条件 锁
data = ""
"""
conn 为新的套接字对象,可以用来接收和发送数据。
address是连接客户端的地址接收TCP客户的连接
"""
def NotifyAll(sss):
global data
if con.acquire():#获取锁
data = sss
con.notifyAll()#表示当前线程放弃对资源的占用 通知其他线程
con.release() #释放锁
def ThreadOut(conn,nick):
global data
while True:
if con.acquire():
con.wait()#会阻塞在这里 放弃对当前资源的占用 等
if data:
try:
conn.send(data)#发送
con.release()
except:
con.release()
return
def ThreadIn(conn,nick):#接收消息
while True:
try:
temp = conn.recv(1024)
if not temp:
conn.close()
return
NotifyAll(temp)
print data
except:
NotifyAll(nick+'happen error...')
print "异常数据:",data
return
"""
1、将所有客户端的连接对象,保存到list中
2、服务端将消息转发到其中一个客户端的连接对象
"""
clientlist = []
while True:
conn,address = srv_sock.accept()
print "\n客服端连接地址:",address
print "\nIP:",address[0],"PORT:",address[1]
nick = conn.recv(1024)
print "\n",nick #接收昵称
NotifyAll('Welcome '+nick+' to the room!!!\n')
print data
conn.send(data)
clientlist.append(address)
#conn.sendto("9999999",clientlist[0])
#接收一个数据
#len = sizeof(struct,addr1)
data1,addr1=conn.recvfrom(1024)
print 'Received:',data1,'from:',len(addr1),addr1
print "IP: ",addr1[0],"PORT: ",addr1[1]
conn.sendto(b'this is is IP',(HOST,PORT))
print "\n客户端连接集合个数为:",len(clientlist),clientlist
#print clientlist[0]
#如果连接客户端有2个或以上就将消息发送到第二个客户端上
if len(clientlist)>=2:
print "判断消息:",clientlist[1]
conn.sendto(b'server send ip massage to host', clientlist[1])
threading.Thread(target=ThreadOut,args=(conn,nick)).start()
threading.Thread(target=ThreadIn,args=(conn,nick)).start()
2、ChatClient.py
#!C:/Python27
#coding=utf-8
import socket
import threading
HOST = "localhost"
PORT = 6666
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST,PORT))
print u"建立连接"
outString =""
inString = ""
nick = ""
def client_send(sock):#在函数内部改变全局变量
global outString
global nick
while True:
#死循环 一直监听输入 如果有输入 就会发生到服务端
outString = raw_input("\n请输入要发送的消息: \n >>>: ")#接收输入
outString = nick + '说:'+outString
print "\n",outString
sock.send(outString)
def client_accept(sock):
global inString
while True:
try:
inString = sock.recv(1024)#接收数据
if not inString:
break
if outString != inString:
print inString
except:
break
nick = raw_input(u"请输入您的用户名: \n >>>:")
sock.send(nick)#发送用户名
outStringPord = raw_input("\n给客服端的发送消息的端口是: \n >>>: ")#接收输入端口
poot =('127.0.0.1',int(outStringPord, base=10))#字符串转换为10进制
print poot
sock.sendto(b'hello,this is a test info !',poot)
th_send = threading.Thread(target=client_send,args=(sock,))#发送消息的线程
th_send.start()
th_accept = threading.Thread(target=client_accept,args=(sock,))
th_accept.start()