【发布时间】:2019-04-28 21:01:09
【问题描述】:
我在 GitHub 上找到了一个非常简单的开源 project:可以将相同的 Python 脚本用作服务器或客户端。
import socket
import threading
import queue
import sys
import random
import os
#Client Code
def ReceiveData(sock):
while True:
try:
data,addr = sock.recvfrom(1024)
print(data.decode('utf-8'))
except:
pass
def RunClient(serverIP):
host = socket.gethostbyname(socket.gethostname())
port = random.randint(6000,10000)
print('Client IP->'+str(host)+' Port->'+str(port))
server = (str(serverIP),5000)
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.bind((host,port))
name = input('Please write your name here: ')
if name == '':
name = 'Guest'+str(random.randint(1000,9999))
print('Your name is:'+name)
s.sendto(name.encode('utf-8'),server)
threading.Thread(target=ReceiveData,args=(s,)).start()
while True:
data = input()
if data == 'qqq':
break
elif data=='':
continue
data = '['+name+']' + '->'+ data
s.sendto(data.encode('utf-8'),server)
s.sendto(data.encode('utf-8'),server)
s.close()
os._exit(1)
#Client Code Ends Here
#Server Code
def RecvData(sock,recvPackets):
while True:
data,addr = sock.recvfrom(1024)
recvPackets.put((data,addr))
def RunServer():
host = socket.gethostbyname(socket.gethostname())
port = 5000
print('Server hosting on IP-> '+str(host))
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.bind((host,port))
clients = set()
recvPackets = queue.Queue()
print('Server Running...')
threading.Thread(target=RecvData,args=(s,recvPackets)).start()
while True:
while not recvPackets.empty():
data,addr = recvPackets.get()
if addr not in clients:
clients.add(addr)
continue
clients.add(addr)
data = data.decode('utf-8')
if data.endswith('qqq'):
clients.remove(addr)
continue
print(str(addr)+data)
for c in clients:
if c!=addr:
s.sendto(data.encode('utf-8'),c)
s.close()
#Serevr Code Ends Here
if __name__ == '__main__':
if len(sys.argv)==1:
RunServer()
elif len(sys.argv)==2:
RunClient(sys.argv[1])
else:
print('Run Serevr:-> python Chat.py')
print('Run Client:-> python Chat.py <ServerIP>')
从图片中可以看出,效果非常好:
但我的目标是让服务器也加入聊天。
UDP 聊天室是否可以让服务器在作为服务器工作时也充当客户端?
【问题讨论】:
-
绝对有可能——一种简单的方法是让服务器产生一个线程,然后从线程内调用 RunClient('127.0.0.1')。
-
是否有理由不只运行程序的两个副本(以及在其他机器上运行更多副本)?
-
@JeremyFriesner,我试过了,终端是空的。也许我没有捕捉到服务器本身的数据。如果您知道该怎么做,欢迎提出答案
-
@DavisHerring,这是一个挑战
标签: python sockets udp chat chatroom