【问题标题】:Cant connect to python server无法连接到python服务器
【发布时间】:2014-08-19 11:25:00
【问题描述】:

我是在 python 中使用套接字的新手,所以我想创建简单的服务器:客户端可以连接并等待一段时间。

我的问题是 - 当我从第一个客户端(client.py)连接到服务器时 - 服务器记录了它,但同时我从另一个客户端连接到服务器(平板电脑网络浏览器) - 并且服务器不记录它。他不向第二个客户端发送消息,就好像它不存在一样。但在代码中我有listen(2)

这是否意味着我必须为每个新连接创建新进程?将来我想创建一个非常简单的聊天(多人,2 合一个聊天室)进行培训。或者我可以在 clients 列表中收集有关客户端的连接信息,然后为两个人创建进程吗?

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)

非常感谢!

【问题讨论】:

  • 你的服务器只允许一个连接

标签: python sockets chat


【解决方案1】:

这是因为您的“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/

阅读更多关于套接字和连接的概念,我相信它会对你有所帮助 从长远来看也更多。 希望对您有所帮助。

干杯

【讨论】:

    【解决方案2】:

    您可以在一个过程中处理此问题。

    最简单的方法是串行处理每个连接。等待并接受传入连接,与对等方通信,然后断开连接。然后等待另一个连接。这不能处理您想要多个并发客户端连接的情况,显然它不会扩展。这是处理串行连接的代码修订版:

    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() 和/或 poll() 函数。)。 asyncore module 非常值得一看。 asynchat 可能有你需要的一切。

    另一种选择是为每个客户端创建一个新线程或子进程。

    twisted 是一个更复杂的选项,但是,它的学习曲线很陡峭,可能无法满足您的要求。

    【讨论】:

      【解决方案3】:

      你有listen(2),你需要另一个来自传入连接的处理程序。

      conn, addr = sock.accept() # accept connection
      

      在while循环内。

      【讨论】:

        猜你喜欢
        • 2011-06-19
        • 2018-05-24
        • 2023-02-08
        • 2019-12-22
        • 2014-10-16
        • 1970-01-01
        • 1970-01-01
        • 2020-09-13
        • 1970-01-01
        相关资源
        最近更新 更多