【发布时间】:2016-01-05 07:44:06
【问题描述】:
首先作为免责声明:我不是最擅长 Python(或一般编程)的人。
话虽如此,我遇到了 Python 套接字的问题。我正在尝试构建一个简单的聊天客户端/服务器程序,但是,我无法让服务器将从一个客户端的套接字接收到的相应消息发送到其余连接的客户端。
这是服务器代码:
#!/usr/bin/python
import socket
import fnmatch
import thread
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
## Allow socket to be reused by application - doesn't force timeout.
serverSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
host = socket.gethostname()
port = 9000
serverSocket.bind((host,port))
connectedUsers = []
serverSocket.listen(5)
def threadedClient(clientStream):
while True:
clientMessage = clientStream.recv(1024).decode()
print clientMessage
if "Username:" in clientMessage:
username = clientMessage.replace("Username:","")
print str(username) + " has connected!"
connectedUsers.append(clientAddress)
print str(username) + "" + str(clientAddress) + " has connected to server"
for users in connectedUsers:
clientStream.sendto(str(username) + " has connected!", users)
if "Text:" in clientMessage:
receievedText = clientMessage.replace("Text:","")
for users in connectedUsers:
clientStream.sendto(receievedText.encode(), users)
print "Sending message " + str(receievedText) +" to:" + str(users)
if not clientMessage:
break
while True:
clientStream, clientAddress = serverSocket.accept()
thread.start_new_thread(threadedClient,(clientStream,))
这是客户端代码:
#!/usr/bin/python
import socket
clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "127.0.0.1"
port = 9000
username = raw_input("Please enter username: ")
clientSocket.connect((host, port))
clientSocket.send("Username:" + username)
def receiveServerMessage():
serverMessage = clientSocket.recv(1024).decode()
print serverMessage + '\n'
while True:
receiveServerMessage()
command = raw_input(username + " > ")
if command != None:
clientSocket.send("Text:" + str.encode(command))
if command == str("q"):
exit()
clientSocket.close()
尝试将消息发送到其他连接的客户端时,迭代似乎出错了。我不确定“sendto”是否是处理这种情况的正确方法……尤其是因为我相信它是基于 UDP 的。有关如何正确处理套接字流的任何建议?
【问题讨论】:
-
我建议您开始使用 TCP 而不是 UDP,因为它是一种更简单的方法。
-
@lilezek 在我看来像 tcp socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-
我认为命令“sendto”在某种程度上与 udp 相关的唯一原因是,网上找到的大多数教程/文档都专门与 UDP 相关。但是,机器上的 tcpdump 只显示 TCP 通信。
-
看起来您的 connectedUsers 对象是跨多个线程共享的。鉴于此,您需要使用互斥锁或类似方法序列化对该对象的访问,否则您将面临一个线程修改列表而另一个线程正在从列表中读取的风险,这将导致意外行为。
标签: python multithreading sockets tcp