我是python中使用套接字的新手,所以我想创建简单的服务器:客户端可以连接并等待一段时间。
我的问题是 - 当我从第一个客户端( client.py )连接到服务器时 - 服务器记录它,但同时我从另一个客户端连接到服务器(平板电脑网络浏览器) ) - 并且服务器不记录它。他不向第二个客户端发送消息,就好像它不存在一样。但在代码中我有listen(2)
!
这是否意味着我必须为每个新连接创建新进程?将来我想创建一个非常简单的聊天(许多人,2合一聊天室)进行培训。或者我可以在客户端列表中收集有关客户的连接信息,还是为两个人创建流程?
settings.py
number_of_connections = 2
host = ''
port = 9090
server.py
import time
from socket import socket, AF_INET, SOCK_STREAM
from multiprocessing import Process
from settings import host, port, number_of_connections
def logging(message):
print(message)
with open('log.txt', 'a') as f:
f.write('%s\n' % message)
clients = []
sock = socket(AF_INET, SOCK_STREAM)
sock.bind((host, port))
sock.listen(number_of_connections)
conn, addr = sock.accept() # accept connection. conn - new socket, addr - client`s adress
clients.append((conn, addr))
#conn.settimeout(60)
logging('%s Connection from %s:%s' % (time.ctime(), addr[0], addr[1]))
while True:
data = conn.recv(1024)
if not data:
break
udata = data.decode("utf-8")
logging("Server recieve Data: %s" % udata)
#conn.send(data.upper())
conn.send(b"Hello! From server!\n")
conn.send(b"Your data: " + udata.encode("utf-8"))
# if we had 2 clients, create process?
if len(clients) == 2:
print(clients)
clients.clear()
client.py
from socket import socket, AF_INET, SOCK_STREAM
from settings import host, port
sock = socket(AF_INET, SOCK_STREAM)
sock.connect((host, port))
sock.send(b'hello, world! From client')
while True:
data = sock.recv(1024)
print(data)
非常感谢!
答案 0 :(得分:2)
这是因为你的'conn'变量来自套接字连接的第一个客户端的连接。尝试更改脚本以循环通过sock.accept()
以下是您的server.py,其变化非常小,因此您可以看到差异。
import time
from socket import socket, AF_INET, SOCK_STREAM
from multiprocessing import Process
from settings import host, port, number_of_connections
def logging(message):
print(message)
with open('log.txt', 'a') as f:
f.write('%s\n' % message)
clients = []
sock = socket(AF_INET, SOCK_STREAM)
sock.bind((host, port))
sock.listen(number_of_connections)
while True:
conn, addr = sock.accept()
data = conn.recv(1024)
if not data:
break
udata = data.decode("utf-8")
logging("Server recieve Data: %s" % udata)
conn.send(b"Hello! From server!\n")
conn.send(b"Your data: " + udata.encode("utf-8"))
如果您想了解聊天服务器/客户端的示例,请查看以下内容:
http://code.activestate.com/recipes/531824/
详细了解套接字和连接的概念,我相信它会对您有所帮助 从长远来看也是如此。 希望有所帮助。
欢呼声
答案 1 :(得分:1)
您可以在一个过程中处理此问题。
最简单的方法是串行处理每个连接。等待并接受传入连接,与对等方通信,然后断开连接。然后等待另一个连接。这并不能处理您想要多个并发客户端连接的情况,显然它不会扩展。以下是将处理串行连接的代码修订:
import time
from socket import socket, AF_INET, SOCK_STREAM
from multiprocessing import Process
from settings import host, port, number_of_connections
def logging(message):
print(message)
with open('log.txt', 'a') as f:
f.write('%s\n' % message)
sock = socket(AF_INET, SOCK_STREAM)
sock.bind((host, port))
sock.listen(number_of_connections)
while True:
logging("Waiting for connection on %s:%s" % (host, port))
conn, addr = sock.accept()
logging('%s Connection from %s:%s' % (time.ctime(), addr[0], addr[1]))
while True:
data = conn.recv(1024)
if not data:
# remote closed connection, close and wait for a new connection
logging("Client closed connection")
conn.close()
break
udata = data.decode("utf-8")
logging("Server recieve Data: %s" % udata)
#conn.send(data.upper())
conn.send(b"Hello! From server!\n")
conn.send(b"Your data: " + udata.encode("utf-8"))
但是,因为您实际上想要处理多个并发连接,所以现在可以调查select module,它提供了帮助异步IO的功能(请参阅select()
和/或{{ 1}}函数。)。 asyncore module非常值得一看。 asynchat可能拥有您需要的一切。
另一种选择是为每个客户创建一个新线程或子流程。
更复杂的选项是twisted,但是,学习曲线陡峭,对您的要求可能过度。
答案 2 :(得分:0)
你有监听(2),你需要来自传入连接的另一个处理程序。
放
conn, addr = sock.accept() # accept connection
在while循环中。