一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術(shù)及教程分享平臺(tái)!
分類導(dǎo)航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務(wù)器之家 - 腳本之家 - Python - Python實(shí)現(xiàn)一個(gè)服務(wù)器監(jiān)聽多個(gè)客戶端請(qǐng)求

Python實(shí)現(xiàn)一個(gè)服務(wù)器監(jiān)聽多個(gè)客戶端請(qǐng)求

2021-01-31 00:04驚瑟 Python

這篇文章主要為大家詳細(xì)介紹了Python如何實(shí)現(xiàn)一個(gè)服務(wù)器監(jiān)聽多個(gè)客戶端請(qǐng)求,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

學(xué)習(xí)python網(wǎng)絡(luò)通信的時(shí)候發(fā)現(xiàn)書上只有一個(gè)服務(wù)端對(duì)應(yīng)一個(gè)客戶端的情形,于是自己想自己動(dòng)手實(shí)現(xiàn)一個(gè)服務(wù)端響應(yīng)多個(gè)客戶端。

首先建立服務(wù)器的socket來監(jiān)聽客戶端的請(qǐng)求:

?
1
2
3
tcpsersock=socket(af_inet,sock_stream)
tcpsersock.bind(addr)
tcpsersock.listen(5)

這樣服務(wù)器的監(jiān)聽socket就建好了。

接下來的思路是,如果要監(jiān)聽多個(gè)客戶端,則

?
1
tcpsersock.accept() #(accept()是阻塞式的)

必須放進(jìn)一個(gè)while循環(huán)(不放進(jìn)循環(huán)監(jiān)聽一次就沒了)。然而,這里就有問題了。如果按照一對(duì)一的那種處理順序,客戶端a連進(jìn)來后,程序順序向下執(zhí)行,服務(wù)端要再寫一個(gè)while循環(huán),用來處理客戶端a的請(qǐng)求,如果此時(shí)客戶端b再來請(qǐng)求,服務(wù)器將接收不到。于是,很自然想到,將監(jiān)聽和處理放到不同的線程進(jìn)行處理。我選擇將監(jiān)聽放入主線程,將處理放進(jìn)子線程。該服務(wù)器功能為接收到客戶端的數(shù)據(jù)加上時(shí)間戳后返回給客戶端。服務(wù)端完整代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#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=[]        #放每個(gè)客戶端的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)) #加上時(shí)間戳返回
 
t = threading.thread(target=handle)    #子線程
if __name__ == '__main__':
 t.start()
 print u'我在%s線程中 ' % threading.current_thread().name #本身是主線程
 print 'waiting for connecting...'
 while true:
  clientsock,addr = tcpsersock.accept()
  print 'connected from:', addr
  socks.append(clientsock)

兩個(gè)客戶端a和b同時(shí)連接,服務(wù)器輸出:

Python實(shí)現(xiàn)一個(gè)服務(wù)器監(jiān)聽多個(gè)客戶端請(qǐng)求

可以看到服務(wù)端是可以相應(yīng)多個(gè)客戶端的。

客戶端a發(fā)條消息試試?

Python實(shí)現(xiàn)一個(gè)服務(wù)器監(jiān)聽多個(gè)客戶端請(qǐng)求

服務(wù)器返回來了帶時(shí)間戳的消息,goodjob。

那另一個(gè)呢?

Python實(shí)現(xiàn)一個(gè)服務(wù)器監(jiān)聽多個(gè)客戶端請(qǐng)求

很棒。服務(wù)器都能做出響應(yīng)。

再發(fā)一條試試?

Python實(shí)現(xiàn)一個(gè)服務(wù)器監(jiān)聽多個(gè)客戶端請(qǐng)求

發(fā)現(xiàn)服務(wù)器沒響應(yīng)了,這是怎么回事呢?

經(jīng)過仔細(xì)勘察發(fā)現(xiàn)是因?yàn)檫@句:

?
1
data = s.recv(bufsiz)

因?yàn)閞ecv方法是阻塞的,也就是說,當(dāng)輪訓(xùn)到某個(gè)客戶端,比如a,這句等待a發(fā)消息,不發(fā)消息就不往下走,所以此時(shí)b再去發(fā)消息的話服務(wù)器就收不到了。

那該怎么辦呢?

很容易想到,將其設(shè)為非阻塞就好了。但上網(wǎng)找了好久,雖然找到可以用setblocking(0)  將套接字設(shè)為非阻塞,然而具體怎么用卻很少有人講清楚。查資料后終于搞明白,非阻塞的recv方法會(huì)繼續(xù)向下執(zhí)行,若超時(shí)得不到數(shù)據(jù)則會(huì)拋出異常。

修改后的代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#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=[]        #放每個(gè)客戶端的socket
 
def handle():
 while true:
  for s in socks:
   try:
    data = s.recv(bufsiz)  #到這里程序繼續(xù)向下執(zhí)行
   except exception, e:  
    continue
   if not data:
    socks.remove(s)
    continue
   s.send('[%s],%s' % (ctime(), data))
 
t = threading.thread(target=handle)    #子線程
if __name__ == '__main__':
 t.start()
 print u'我在%s線程中 ' % threading.current_thread().name #本身是主線程
 print 'waiting for connecting...'
 while true:
  clientsock,addr = tcpsersock.accept()
  print 'connected from:', addr
  clientsock.setblocking(0)
  socks.append(clientsock)

此時(shí)再去嘗試:

Python實(shí)現(xiàn)一個(gè)服務(wù)器監(jiān)聽多個(gè)客戶端請(qǐng)求

客戶端隨便輸都會(huì)得到響應(yīng)。任務(wù)達(dá)成!

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://blog.csdn.net/qq_34062683/article/details/78063035

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: asianfemdom妍妍女王 | 无限在线观看视频大全免费高清 | 俄罗斯女人与公拘i交酡 | 国产午夜一区二区在线观看 | 亚洲精品国产自在现线最新 | 99热精品国产麻豆 | 国产精品久久久久jk制服 | avtt一区| 国产成人久久久精品一区二区三区 | 无码日韩精品一区二区免费 | 双性总裁(h) | 无人在线视频高清免费播放 | 思思玖玖玖在线精品视频 | 成人在线日韩 | 精品欧美男同同性videos | 日日精品 | 蜜桃视频一区二区 | 久久99精品久久久久久园产越南 | s8sp加密路线和免费路线首页 | 国产成人精品一区二区阿娇陈冠希 | 久久人妻熟女中文字幕AV蜜芽 | 色色色资源站 | 日韩欧美一区黑人vs日本人 | 四虎最新免费网址 | 欧美视频一区二区三区四区 | 欧美vpswindowssex 欧美va在线高清 | 99久久精品免费观看区一 | 色中文字幕 | 日本免费一区二区三区a区 日本免费三片在线观看 | 四虎影院在线免费 | 国产大秀视频一区二区三区 | 欧美国产高清 | 久久理论片| www.天天操| 亚欧美综合 | 色女的乖男人 | 好男人好资源在线观看免费 | 第一福利在线观看永久视频 | nxgx国产 | 视频在线观看高清免费 | 国产丰满美女做爰 |