我试图制造一个可以连接多个客户端的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
随时更改您想要的任何内容。 如果您需要任何其他信息,只需询问。
答案 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,将导致以下两个连接: