本文實(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入門與進(jìn)階經(jīng)典教程》及《Python文件與目錄操作技巧匯總》
希望本文所述對(duì)大家Python程序設(shè)計(jì)有所幫助。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
