Reputation: 35
I'm trying to make a Python server where multiple clients can connect but I've run into a problem I tried everything that I found on the internet. I'm running a laptop whit windows 7 and an I3 processor.
This is the file called 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()
This is the server:
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()
This is the client:
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)
The error is:
[WinError 10048]Only one usage of each socket address (protocol/network address/port) is normally permitted Python
Feel free to change anything you want. If you need any info in plus just ask.
Upvotes: 0
Views: 6258
Reputation: 12347
You are creating a socket in the client with tcp.make_client
. You are then using that socket to connect to the server via tcp.client_connect
. Presumably you successfully receive the new port number back from the server. But then you are trying to re-use the same socket to connect to those ports.
This is the proximate cause of your error: A socket can only be used for a single TCP connection. If you want to create a new connection, you must first create a new socket.
That being said, if you are simply trying to create a server that will accept multiple connections, you're making it way too complicated. The server can receive any number of connections on its single listening port, as long as a different address/port combination is used by each client.
One way to structure this in a server is something like this:
# 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?)
There are several others ways to do it as well: you can create multiple threads to handle multiple connections, or you can handle all connections in a single thread by using select
or with asynchronous I/O.
The client is typically much simpler -- as it usually only cares about its own one connection -- and doesn't care which way the server is implemented:
sock = socket.socket()
sock.connect((ip, port))
while True:
sock.send(...)
sock.recv(...)
If the client does wish to connect to the same server again, it simply creates a second socket and call its connect
method with the same server IP and port.
Usually, the client never needs to specify its own port, only the server's port. It simply calls connect
and the client-side operating system chooses an unused port for it. So the first time, the client creates a socket and connects it (to the server's listening port), the client-side OS may choose port 50001. The next time it creates and connects a socket, it may get 50002 and so on. (The exact port numbers chosen depend on the operating system implementation and other factors, such as what other programs are running and creating connections.)
So, given client IP 192.168.0.101 and server IP 192.168.0.102, and assuming the server is listening on port 8000, this would result in these two connections:
Upvotes: 3