如何使TCP服务器处理多个客户端?

时间:2019-03-03 17:17:36

标签: python windows sockets

我试图制造一个可以连接多个客户端的Python服务器,但是遇到了一个问题,我尝试了我在互联网上找到的所有内容。 我正在运行Windows 7和I3处理器的笔记本电脑。

这是名为 tcp 的文件:

import socket

def make_server (ip,port):
    try:
        server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server.bind((ip, port))
        server.listen(1)
        return server
    except Exception as ex:
        print(ex)
        return None


def accept(server):
    conn, addr = server.accept()
    return conn

def make_client():
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    return client

def client_connect(client,ip,port):
    client.connect((ip,port))

def sendall(conn,mess):
    conn.send(str(mess).encode("utf-8"))

def rec(conn,rate):
    mess = conn.recv(rate).decode("utf-8")
    return mess

def close(client):
    client.close()

这是服务器

from multiprocessing import Process
from random import randint
import tcp
import sys


def start(sip, sport):
    print("Making sob server...")
    print("id= {}".format(sport))
    sserver = tcp.make_server(sip, sport)
    print("Sub Server Started!")
    sconn = tcp.accept(sserver)
    tcp.sendall(sconn, "connected!!")
    while True:
        try:
            tcp.sendall(sconn, randint(0, 100))
        except Exception as ex:
            print("")
            print("From server {} error:".format(port))
            print(ex)
            print("")
            break


ip = "192.168.0.102"
port = 8000
subport = 9000
server = tcp.make_server(ip, port)
if server is None:
    sys.exit(0)
print("Started!")
while True:
    print("Wating for new connection!")
    con = tcp.accept(server)
    print("Connected!")
    subport = subport + 1
    tcp.sendall(con, subport)
    print("New Port Sent!")
    print("New Port = {}".format(subport))
    subs = Process(target=start, args=(ip, subport))
    subs.start()
    subs.join()

这是客户端

import tcp
import time

nport = 0
ip = "192.168.0.102"
port = 8000
client = tcp.make_client()
tcp.client_connect(client,ip,port)
nport = tcp.rec(client,1024)
print(nport)
tcp.close(client)
nport = int(nport)
time.sleep(1)
print(nport)
client = tcp.make_client()
tcp.client_connect(client,ip,nport)
while True:
    mess = tcp.rec(client, 1024)
    if(mess):
        print(mess)

错误是:

[WinError 10048]Only one usage of each socket address (protocol/network address/port) is normally permitted Python

随时更改您想要的任何内容。 如果您需要任何其他信息,只需询问。

1 个答案:

答案 0 :(得分:0)

您正在使用tcp.make_client在客户端中创建套接字。然后,您将使用该套接字通过tcp.client_connect连接到服务器。大概您已经成功从服务器收到了新的端口号。但是,然后您尝试重新使用相同的套接字连接到这些端口。

这是导致错误的最直接原因:套接字只能用于单个TCP连接。如果要创建新的连接,则必须首先创建一个新的套接字。

话虽如此,如果您只是尝试创建一个可以接受多个连接的服务器,那么您将使其变得过于复杂。只要每个客户端使用不同的地址/端口组合,服务器就可以在其单个侦听端口上接收任意数量的连接。

在服务器中进行结构化的一种方法是这样的:

# Create and bind listening socket
lsock = socket.socket()
lsock.bind(('', port))
lsock.listen(1)
while True:    
    csock, addr = lsock.accept()
    print("Got connection from {}".format(addr))

    # Start sub-process passing it the newly accepted socket as argument
    subs = Process(target=start, args=(csock, ))
    subs.start()

    # Close our handle to the new socket (it will remain open in the 
    # sub-process which will use it to talk to the client)
    csock.close()

    # NOTE: do not call subs.join here unless you want the parent to *block* 
    # waiting for the sub-process to finish (and if so, what is the point in 
    # creating a sub-process?)

还有其他几种方法可以执行此操作:您可以创建多个线程来处理多个连接,或者可以使用select或异步I / O处理单个线程中的所有连接。

客户端通常要简单得多-因为它通常只关心自己的一个连接-并不关心服务器的实现方式:

sock = socket.socket()
sock.connect((ip, port))
while True:
    sock.send(...)
    sock.recv(...)

如果客户端希望再次连接到同一台服务器,则只需创建第二个套接字并使用相同的服务器IP和端口调用其connect方法。

通常,客户端不需要指定自己的端口,而只需指定服务器的端口。它仅调用connect,客户端操作系统为此选择一个未使用的端口。因此,客户端第一次创建套接字并将其连接(到服务器的监听端口),客户端操作系统可能会选择端口50001。下次创建并连接套接字时,它可能会得到50002等等。 (选择的确切端口号取决于操作系统的实现和其他因素,例如正在运行其他程序的程序以及如何创建连接。)

因此,给定客户端IP 192.168.0.101和服务器IP 192.168.0.102,并假设服务器正在侦听端口8000,将导致以下两个连接:

  • (192.168.0.101/50001)====>(192.168.0.102/8000)
  • (192.168.0.101/50002)====>(192.168.0.102/8000)