Python實(shí)現(xiàn)的服務(wù)器示例小結(jié)【單進(jìn)程、多進(jìn)程、多線程、非阻塞式】
本文實(shí)例講述了Python實(shí)現(xiàn)的服務(wù)器。分享給大家供大家參考,具體如下:
python - 單進(jìn)程服務(wù)器
#coding=utf-8
from socket import *
#創(chuàng)建套接字
serSocket = socket(AF_INET, SOCK_STREAM)
#重復(fù)使用綁定信息
serSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
localAddr = ('', 7788)
#綁定端口ip
serSocket.bind(localAddr)
#監(jiān)聽(tīng)
serSocket.listen(5)
while True:
print('---主進(jìn)程,等待新客戶端的到來(lái)---')
newSocket,destAddr = serSocket.accept()
print('---主進(jìn)程,接下來(lái)負(fù)責(zé)數(shù)據(jù)處理[%s]---'%str(destAddr))
try:
while True:
recvData = newSocket.recv(1024)
if len(recvData)>0:
print('recv[%s]:%s'%(str(destAddr),recvData))
else:
print('[%s]客戶端已經(jīng)關(guān)閉')
break
finally:
newSocket.close()
serSocket.close()
總結(jié)
同一時(shí)刻只能為一個(gè)客戶進(jìn)行服務(wù),不能同時(shí)為多個(gè)客戶服務(wù)。
當(dāng)服務(wù)器為一個(gè)客戶端服務(wù)時(shí),另外的客戶端發(fā)起了connect,只要服務(wù)器listen的隊(duì)列有空閑的位置,就會(huì)為這個(gè)新客戶端進(jìn)行連接,并且客戶端可以發(fā)送數(shù)據(jù),但當(dāng)服務(wù)器為這個(gè)新客戶端服務(wù)時(shí),可能一次性把所有數(shù)據(jù)接收完畢當(dāng)recv接收數(shù)據(jù)時(shí),返回值為空,即沒(méi)有返回?cái)?shù)據(jù),那么意味著客戶端已經(jīng)調(diào)用了close關(guān)閉了;因此服務(wù)器通過(guò)判斷recv接收數(shù)據(jù)是否為空 來(lái)判斷客戶端是否已經(jīng)下線。
python - 多進(jìn)程服務(wù)器
#coding=utf-8
from socket import *
from multiprocessing import *
from time import sleep
#處理客戶端的請(qǐng)求并為其服務(wù)
def dealWithClient(newSocket,destAddr):
try:
while True:
recvData = newSocket.recv(1024)
if len(recvData) > 0:
print('recv[%s]:%s' % (str(destAddr), recvData))
else:
print('[%s]客戶端已經(jīng)關(guān)閉')
break
finally:
newSocket.close()
def main():
#創(chuàng)建套接字
serSocket = socket(AF_INET, SOCK_STREAM)
#重復(fù)使用綁定信息
serSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
localAddr = ('', 7788)
#綁定端口ip
serSocket.bind(localAddr)
#監(jiān)聽(tīng)
serSocket.listen(5)
try:
while True:
print('---主進(jìn)程,等待新客戶端的到來(lái)---')
newSocket,destAddr = serSocket.accept()
print('---主進(jìn)程,接下來(lái)負(fù)責(zé)數(shù)據(jù)處理[%s]---'%str(destAddr))
client = Process(target=dealWithClient, args=(newSocket, destAddr))
client.start()
# 因?yàn)橐呀?jīng)向子進(jìn)程中copy了一份(引用),并且父進(jìn)程中這個(gè)套接字也沒(méi)有用處了
# 所以關(guān)閉
newSocket.close()
finally:
# 當(dāng)為所有的客戶端服務(wù)完之后再進(jìn)行關(guān)閉,表示不再接收新的客戶端的鏈接
serSocket.close()
if __name__ == '__main__':
main()
總結(jié)
通過(guò)為每個(gè)客戶端創(chuàng)建一個(gè)進(jìn)程的方式,能夠同時(shí)為多個(gè)客戶端進(jìn)行服
務(wù)當(dāng)客戶端不是特別多的時(shí)候,這種方式還行,如果有成百上千個(gè),就不
可取了,因?yàn)槊看蝿?chuàng)建進(jìn)程的過(guò)程需要消耗較多的資源。
python - 多線程服務(wù)器
#coding=utf-8
from socket import *
from threading import Thread
from time import sleep
# 處理客戶端的請(qǐng)求并執(zhí)行事情
def dealWithClient(newSocket,destAddr):
while True:
recvData = newSocket.recv(1024)
if len(recvData)>0:
print('recv[%s]:%s'%(str(destAddr), recvData))
else:
print('[%s]客戶端已經(jīng)關(guān)閉'%str(destAddr))
break
newSocket.close()
def main():
serSocket = socket(AF_INET, SOCK_STREAM)
serSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR , 1)
localAddr = ('', 7788)
serSocket.bind(localAddr)
serSocket.listen(5)
try:
while True:
print('-----主進(jìn)程,,等待新客戶端的到來(lái)------')
newSocket,destAddr = serSocket.accept()
print('-----主進(jìn)程,,接下來(lái)創(chuàng)建一個(gè)新的進(jìn)程負(fù)責(zé)數(shù)據(jù)處理[%s]----'%str(destAddr))
client = Thread(target=dealWithClient, args=(newSocket,destAddr))
client.start()
#因?yàn)榫€程中共享這個(gè)套接字,如果關(guān)閉了會(huì)導(dǎo)致這個(gè)套接字不可用,
#但是此時(shí)在線程中這個(gè)套接字可能還在收數(shù)據(jù),因此不能關(guān)閉
#newSocket.close()
finally:
# 當(dāng)為所有的客戶端服務(wù)完之后再進(jìn)行關(guān)閉,表示不再接收新的客戶端的鏈接
serSocket.close()
if __name__ == '__main__':
main()
單進(jìn)程服務(wù)器-非堵塞模式
服務(wù)器:
#coding=utf-8
from socket import *
import time
# 用來(lái)存儲(chǔ)所有的新鏈接的socket
g_socketList = []
def main():
serSocket = socket(AF_INET, SOCK_STREAM)
serSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR , 1)
localAddr = ('', 7788)
serSocket.bind(localAddr)
#可以適當(dāng)修改listen中的值來(lái)看看不同的現(xiàn)象
serSocket.listen(1000)
#將套接字設(shè)置為?堵塞
#設(shè)置為?堵塞后,如果accept時(shí),恰巧沒(méi)有客戶端connect,那么accept會(huì)
#產(chǎn)生一個(gè)異常,所以需要try來(lái)進(jìn)行處理
serSocket.setblocking(False)
while True:
#?來(lái)測(cè)試
#time.sleep(0.5)
try:
newClientInfo = serSocket.accept()
except Exception as result:
pass
else:
print("一個(gè)新的客戶端到來(lái):%s"%str(newClientInfo))
newClientInfo[0].setblocking(False)
g_socketList.append(newClientInfo)
# 用來(lái)存儲(chǔ)需要?jiǎng)h除的客戶端信息
needDelClientInfoList = []
for clientSocket,clientAddr in g_socketList:
try:
recvData = clientSocket.recv(1024)
if len(recvData)>0:
print('recv[%s]:%s'%(str(clientAddr), recvData))
else:
print('[%s]客戶端已經(jīng)關(guān)閉'%str(clientAddr))
clientSocket.close()
g_needDelClientInfoList.append((clientSocket,clientAddr))
except Exception as result:
pass
for needDelClientInfo in needDelClientInfoList:
g_socketList.remove(needDelClientInfo)
if __name__ == '__main__':
main()
客戶端:
#coding=utf-8
from socket import *
import random
import time
serverIp = input("請(qǐng)輸入服務(wù)器的ip:")
connNum = input("請(qǐng)輸入要鏈接服務(wù)器的次數(shù)(例如1000):")
g_socketList = []
for i in range(int(connNum)):
s = socket(AF_INET, SOCK_STREAM)
s.connect((serverIp, 7788))
g_socketList.append(s)
print(i)
while True:
for s in g_socketList:
s.send(str(random.randint(0,100)))
# 用來(lái)測(cè)試
#time.sleep(1)
更多關(guān)于Python相關(guān)內(nèi)容可查看本站專題:《Python Socket編程技巧總結(jié)》、《Python數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Python函數(shù)使用技巧總結(jié)》、《Python字符串操作技巧匯總》、《Python入門(mén)與進(jìn)階經(jīng)典教程》及《Python文件與目錄操作技巧匯總》
希望本文所述對(duì)大家Python程序設(shè)計(jì)有所幫助。
- python 多進(jìn)程和多線程使用詳解
- Python全局鎖中如何合理運(yùn)用多線程(多進(jìn)程)
- python線程安全及多進(jìn)程多線程實(shí)現(xiàn)方法詳解
- Python實(shí)現(xiàn)多線程/多進(jìn)程的TCP服務(wù)器
- python多線程與多進(jìn)程及其區(qū)別詳解
- Python中單線程、多線程和多進(jìn)程的效率對(duì)比實(shí)驗(yàn)實(shí)例
- Python多線程處理實(shí)例詳解【單進(jìn)程/多進(jìn)程】
- Python并發(fā):多線程與多進(jìn)程的詳解
- Python實(shí)現(xiàn)的多進(jìn)程和多線程功能示例
- Python多線程與多進(jìn)程相關(guān)知識(shí)總結(jié)
相關(guān)文章
python接口自動(dòng)化(十六)--參數(shù)關(guān)聯(lián)接口后傳(詳解)
這篇文章主要介紹了python接口自動(dòng)化參數(shù)關(guān)聯(lián)接口,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
Python關(guān)于拓?fù)渑判蛑R(shí)點(diǎn)講解
在本篇文章里小編給大家分享了一篇關(guān)于Python關(guān)于拓?fù)渑判蛑R(shí)點(diǎn)講解內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。2021-01-01
django框架如何集成celery進(jìn)行開(kāi)發(fā)
本文給大家詳細(xì)講解了在django框架中如何集成celery進(jìn)行開(kāi)發(fā),步驟非常詳細(xì),有需要的小伙伴可以參考下2017-05-05
python函數(shù)裝飾器構(gòu)造和參數(shù)傳遞
這篇文章主要介紹了python函數(shù)裝飾器構(gòu)造和參數(shù)傳遞,下面通過(guò)一個(gè)小案例來(lái)簡(jiǎn)單的理解什么是裝飾器,需要的小伙伴可以參考一下2022-03-03
python結(jié)合opencv實(shí)現(xiàn)人臉檢測(cè)與跟蹤
在Python下用起來(lái)OpenCV很爽,代碼很簡(jiǎn)潔,很清晰易懂。使用的是Haar特征的分類器,訓(xùn)練之后得到的數(shù)據(jù)存在一個(gè)xml中。下面我們就來(lái)詳細(xì)談?wù)劇?/div> 2015-06-06
python的unittest測(cè)試類代碼實(shí)例
這篇文章主要介紹了python的unittest測(cè)試類代碼實(shí)例,具有一定參考價(jià)值,需要的朋友可以了解下。2017-12-12最新評(píng)論

