您好,登錄后才能下訂單哦!
這篇文章主要介紹Python如何實現服務器,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
具體如下:
python - 單進程服務器
#coding=utf-8 from socket import * #創建套接字 serSocket = socket(AF_INET, SOCK_STREAM) #重復使用綁定信息 serSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) localAddr = ('', 7788) #綁定端口ip serSocket.bind(localAddr) #監聽 serSocket.listen(5) while True: print('---主進程,等待新客戶端的到來---') newSocket,destAddr = serSocket.accept() print('---主進程,接下來負責數據處理[%s]---'%str(destAddr)) try: while True: recvData = newSocket.recv(1024) if len(recvData)>0: print('recv[%s]:%s'%(str(destAddr),recvData)) else: print('[%s]客戶端已經關閉') break finally: newSocket.close() serSocket.close()
總結
同一時刻只能為一個客戶進行服務,不能同時為多個客戶服務。
當服務器為一個客戶端服務時,另外的客戶端發起了connect,只要服務器listen的隊列有空閑的位置,就會為這個新客戶端進行連接,并且客戶端可以發送數據,但當服務器為這個新客戶端服務時,可能一次性把所有數據接收完畢當recv接收數據時,返回值為空,即沒有返回數據,那么意味著客戶端已經調用了close關閉了;因此服務器通過判斷recv接收數據是否為空 來判斷客戶端是否已經下線。
python - 多進程服務器
#coding=utf-8 from socket import * from multiprocessing import * from time import sleep #處理客戶端的請求并為其服務 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]客戶端已經關閉') break finally: newSocket.close() def main(): #創建套接字 serSocket = socket(AF_INET, SOCK_STREAM) #重復使用綁定信息 serSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) localAddr = ('', 7788) #綁定端口ip serSocket.bind(localAddr) #監聽 serSocket.listen(5) try: while True: print('---主進程,等待新客戶端的到來---') newSocket,destAddr = serSocket.accept() print('---主進程,接下來負責數據處理[%s]---'%str(destAddr)) client = Process(target=dealWithClient, args=(newSocket, destAddr)) client.start() # 因為已經向子進程中copy了一份(引用),并且父進程中這個套接字也沒有用處了 # 所以關閉 newSocket.close() finally: # 當為所有的客戶端服務完之后再進行關閉,表示不再接收新的客戶端的鏈接 serSocket.close() if __name__ == '__main__': main()
總結
通過為每個客戶端創建一個進程的方式,能夠同時為多個客戶端進行服
務當客戶端不是特別多的時候,這種方式還行,如果有成百上千個,就不
可取了,因為每次創建進程的過程需要消耗較多的資源。
python - 多線程服務器
#coding=utf-8 from socket import * from threading import Thread from time import sleep # 處理客戶端的請求并執行事情 def dealWithClient(newSocket,destAddr): while True: recvData = newSocket.recv(1024) if len(recvData)>0: print('recv[%s]:%s'%(str(destAddr), recvData)) else: print('[%s]客戶端已經關閉'%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('-----主進程,,等待新客戶端的到來------') newSocket,destAddr = serSocket.accept() print('-----主進程,,接下來創建一個新的進程負責數據處理[%s]----'%str(destAddr)) client = Thread(target=dealWithClient, args=(newSocket,destAddr)) client.start() #因為線程中共享這個套接字,如果關閉了會導致這個套接字不可用, #但是此時在線程中這個套接字可能還在收數據,因此不能關閉 #newSocket.close() finally: # 當為所有的客戶端服務完之后再進行關閉,表示不再接收新的客戶端的鏈接 serSocket.close() if __name__ == '__main__': main()
單進程服務器-非堵塞模式
服務器:
#coding=utf-8 from socket import * import time # 用來存儲所有的新鏈接的socket g_socketList = [] def main(): serSocket = socket(AF_INET, SOCK_STREAM) serSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR , 1) localAddr = ('', 7788) serSocket.bind(localAddr) #可以適當修改listen中的值來看看不同的現象 serSocket.listen(1000) #將套接字設置為?堵塞 #設置為?堵塞后,如果accept時,恰巧沒有客戶端connect,那么accept會 #產生一個異常,所以需要try來進行處理 serSocket.setblocking(False) while True: #?來測試 #time.sleep(0.5) try: newClientInfo = serSocket.accept() except Exception as result: pass else: print("一個新的客戶端到來:%s"%str(newClientInfo)) newClientInfo[0].setblocking(False) g_socketList.append(newClientInfo) # 用來存儲需要刪除的客戶端信息 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]客戶端已經關閉'%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("請輸入服務器的ip:") connNum = input("請輸入要鏈接服務器的次數(例如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))) # 用來測試 #time.sleep(1)
以上是“Python如何實現服務器”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。