Study Python It is found that there is only one server corresponding to one client in the book during network communication , So I want to implement one server responding to multiple clients by myself .
First, set up the server socket To listen to client requests :
tcpSerSock=socket(AF_INET,SOCK_STREAM)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(5)
So the server listens socket It's built .
The next idea is , If you want to listen to multiple clients , betcpSerSock.accept() #(accept() It's blocking )
Must put one while loop ( If you don't put it into the loop to monitor once, it's gone ). However , There's a problem here . If you follow the one-to-one processing order , client A After joining in , The program is executed down in sequence , The server needs to write another while loop , To handle clients A Request , If the client at this time B Ask again , The server will not receive . therefore , It's natural to think of , Put listening and processing into different threads for processing . I choose to put listening in the main thread , Put processing into child threads . The server function is to return the data received from the client with time stamp to the client . The complete server code is as follows : #coding=utf-8
#!/usr/bin/env python
'''
author:Mr.Jing
created on Fri Sep 22 14:29:03 2017
platfrom:win10,python2.7
'''
from socket import *
from time import ctime
import threading
import time
HOST=''
PORT=2159
BUFSIZ=1024
ADDR = (HOST,PORT)
tcpSerSock=socket(AF_INET,SOCK_STREAM)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(5)
socks=[] # For each client socket
def handle():
while True:
for s in socks:
data = s.recv(BUFSIZ)
if not data:
socks.remove(s)
continue
s.send('[%s],%s' % (ctime(), data)) # Add a timestamp to return
t = threading.Thread(target=handle) # Sub thread
if __name__ == '__main__':
t.start()
print u' I am here %s In the thread ' % threading.current_thread().name # Itself is the main thread
print 'waiting for connecting...'
while True:
clientSock,addr = tcpSerSock.accept()
print 'connected from:', addr
socks.append(clientSock)
You can see that the server can correspond to multiple clients .
client A Try sending a message ?
The server returned a message with a timestamp ,goodjob.
What about the other one ?
great . The server can respond .
Try sending another one ?
It is found that the server is not responding , What's going on here ?
After careful investigation, it is found that this sentence :
data = s.recv(BUFSIZ)
because recv Method is blocked , in other words , When the rotation training reaches a certain client , such as A, Wait A Send a message , Don't go down without sending messages , So at this time B If you send messages again, the server will not receive them .
So what should we do ?
It's easy to think , Just make it non blocking . But I have been looking for it on the Internet for a long time , Although it can be used setblocking(0) Set socket to non blocking , However, few people have made it clear how to use it . After checking the data, I finally figured out , Non blocking recv Method will continue down , If data is not available after timeout, an exception will be thrown .
The modified code is as follows :
#coding=utf-8
#!/usr/bin/env python
'''
author:Mr.Jing
created on Fri Sep 22 14:29:03 2017
platfrom:win10,python2.7
'''
from socket import *
from time import ctime
import threading
import time
HOST=''
PORT=2159
BUFSIZ=1024
ADDR = (HOST,PORT)
tcpSerSock=socket(AF_INET,SOCK_STREAM)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(5)
socks=[] # For each client socket
def handle():
while True:
for s in socks:
try:
data = s.recv(BUFSIZ) # Here the program continues down
except Exception, e:
continue
if not data:
socks.remove(s)
continue
s.send('[%s],%s' % (ctime(), data))
t = threading.Thread(target=handle) # Sub thread
if __name__ == '__main__':
t.start()
print u' I am here %s In the thread ' % threading.current_thread().name # Itself is the main thread
print 'waiting for connecting...'
while True:
clientSock,addr = tcpSerSock.accept()
print 'connected from:', addr
clientSock.setblocking(0)
socks.append(clientSock)
Client code : Client code
The client will get a response if it just inputs . Mission accomplished !
ps: Just blogged , Not used to this editor , The typesetting is slightly ugly , Please ignore ~