Python基礎筆記系列十三:socket網絡編程
阿新 • • 發佈:2018-05-04
forever %s 如果 主機名 關閉連接 try 控制臺 utf-8 target
本系列教程供個人學習筆記使用,如果您要瀏覽可能需要其它編程語言基礎(如C語言),why?因為我寫得爛啊,只有我自己看得懂!!
使用python編寫一個簡易的服務端程序和客戶端程序,啟動服務端和客戶端(監聽的ip和端口一致),服務端對客戶端進行指定Ip和端口的監聽,實現接收客戶端發送的數據以及對客戶端發送數據。
- 使用原生socket
主要運用到python的socket模塊,直接使用自己的代碼進行socket對象的創建、ip和端口的綁定、接收和發送數據等操作。
服務端:server1.py1 #incoding:utf-8 2 3 #下面這個例子是直接用socket來編程 4 #server1 :
客戶端:client1.py
1 #incoding:utf-8 2 #server1的客戶端程序
寫好服務端和客戶端程序,現在進行測試。
首先啟動服務端進行ip端口監聽,如果端口被占用,嘗試更換端口,範圍是0到65535或者停用端口占用,看這裏傳送門:http://www.cnblogs.com/hyyq/p/6747356.html
服務端啟動成功後,啟動客戶端程序(這裏需要輸入內容,所以需要安裝REPL插件哦,如果沒有,看這裏傳送門:http://www.cnblogs.com/hyyq/p/8909129.html)
這時候在客戶端輸入數據,並會輸出服務端返回的數據,如:1 Please input cmd:123456 2 yours data:123456 3 Please input cmd:abc 4 yours data:abc 5 Please input cmd:
服務端控制臺就會輸出:
1 connect by (‘127.0.0.1‘, 9848) 2 客戶端發送過來的數據:123456 3 客戶端發送過來的數據:abc
- 使用socketserver
python也有封裝好的可以用,比如:socketserver,可以快速進行一個簡單的socket通信。需要導入SocketServer模塊的TCPServer,BaseRequestHandler類,然後我們自己的類從BaseRequestHandler繼承,並重寫handle方法,然後可以很簡單的就可以接收發送數據。
服務端:server2.py1 #incoding:utf-8 2 from SocketServer import TCPServer,BaseRequestHandler 3 import traceback 4 #python也有封裝好的可以用,比如:socketserver 5 #從BaseRequestHandler繼承,並重寫handle方法,然後可以很簡單的就可以接收發送數據 6 class MyBaseRequestHandler(BaseRequestHandler): 7 ‘‘‘ 8 從BaseRequestHandler繼承,並重寫handle方法 9 ‘‘‘ 10 def handle(self): 11 #循環監聽(讀取)來自客戶端的數據 12 while True: 13 #當客戶端主動斷開連接時,self.read(1024)會拋出異常 14 try: 15 #一次讀取1024字節,並取出兩端的空白字符(包括空格,Tab,\r,\n) 16 data = self.request.recv(1024).strip() 17 18 #self.client_address是客戶端的連接(host,post)的元組 19 print "receive from (%r):%r"%(self.client_address,data) 20 21 #轉換成大寫後回寫給客戶端 22 self.request.sendall(data.upper()+"\n") 23 except: 24 traceback.print_exc() 25 break 26 27 if __name__ == ‘__main__‘: 28 #telnet 127.0.0.1 8081 29 host = "127.0.0.1" #主機名,可以是ip,像localhost的主機名或"" 30 port = 8081 #端口 31 addr = (host,port) 32 33 #構造TCPServer對象 34 server = TCPServer(addr, MyBaseRequestHandler) 35 #啟動服務監聽 36 server.serve_forever()
客戶端:client2.py
1 #incoding:utf-8 2 #server2的客戶端程序 3 from socket import * 4 HOST=‘127.0.0.1‘ 5 PORT=8081 6 s=socket(AF_INET,SOCK_STREAM) #定義socket類型,網絡通信,TCP 7 s.connect((HOST,PORT)) #要連接的IP與端口 8 while 1: 9 cmd=raw_input("Please input cmd:") #與人交互,輸入命令 10 s.sendall(cmd) #把命令發送給服務端端 11 data=s.recv(1024) #把接收的數據定義為變量 12 print data #輸出變量 13 s.close() #關閉連接
依次各自啟動服務端、客戶端後,客戶端輸入:
1 Please input cmd:123 2 123 3 4 Please input cmd:456 5 456 6 7 Please input cmd:abc 8 ABC 9 10 Please input cmd:
服務端輸出:
1 receive from ((‘127.0.0.1‘, 10458)):‘123‘ 2 receive from ((‘127.0.0.1‘, 10458)):‘456‘ 3 receive from ((‘127.0.0.1‘, 10458)):‘abc‘
- 多線程TCPServer
上面的兩種方式都只支持一個客戶端和一個服務端進行通信,如果需要多個客戶端和一個服務端通信就需要用到ThreadingTCPServer,StreamRequestHandler,我們自己的類MyStreamRequestHandler從StreamRequestHandler繼承,並重寫handle方法,然後可以很簡單的就可以接收發送數據。
服務端:server3.py1 #incoding:utf-8 2 from SocketServer import ThreadingTCPServer,StreamRequestHandler 3 import traceback 4 #python還可以多個客戶端的多線程TCPServer, 5 #從StreamRequestHandler繼承,並重寫handle方法,然後可以很簡單的就可以接收發送數據 6 class MyStreamRequestHandler(StreamRequestHandler): 7 def handle(self): 8 #循環監聽(讀取)來自客戶端的數據 9 while True: 10 print ‘begin...‘ 11 try: 12 # print help(self.rfile) 13 data = self.rfile.readline().strip() 14 15 #self.client_address是客戶端的連接(host,post)的元組 16 print "receive from (%r):%r"%(self.client_address,data) 17 18 #轉換成大寫後回寫給客戶端 19 self.wfile.write(data.upper()+"\n") 20 except: 21 traceback.print_exc() 22 break 23 24 if __name__ == ‘__main__‘: 25 #telnet 127.0.0.1 8080 26 host = "127.0.0.1" #主機名,可以是ip,像localhost的主機名或"" 27 port = 8082 #端口 28 addr = (host,port) 29 30 #ThreadingTCPServer從ThreadingMixIn和TCPServer繼承 31 #類結構:class ThreadingTCPServer(ThreadingMixIn,TCPServer):pass 32 server = ThreadingTCPServer(addr, MyStreamRequestHandler) 33 #啟動服務監聽 34 server.serve_forever()
第一個客戶端:client3_1.py
1 #incoding:utf-8 2 #server3的客戶端程序1 3 #借鑒:https://blog.csdn.net/rebelqsp/article/details/22109925 4 from socket import * 5 HOST=‘127.0.0.1‘ 6 PORT=8082 7 s=socket(AF_INET,SOCK_STREAM) #定義socket類型,網絡通信,TCP 8 s.connect((HOST,PORT)) #要連接的IP與端口 9 while 1: 10 cmd=raw_input("Please input cmd:") #與人交互,輸入命令 11 #註意:發送的字符串內容要加一個回車符即\r\n 12 #因為服務端server3是根據行來讀取的 13 s.sendall("%s\r\n"%cmd) #把命令發送給服務端端 14 # print help(s) 15 data=s.recv(1024) #把接收的數據定義為變量 16 print data #輸出變量 17 s.close() #關閉連接
第二個客戶端:client3_2.py
1 #incoding:utf-8 2 #server3的客戶端程序2 3 from socket import * 4 HOST=‘127.0.0.1‘ 5 PORT=8082 6 s=socket(AF_INET,SOCK_STREAM) #定義socket類型,網絡通信,TCP 7 s.connect((HOST,PORT)) #要連接的IP與端口 8 while 1: 9 cmd=raw_input("Please input cmd:") #與人交互,輸入命令 10 #註意:發送的字符串內容要加一個回車符即\r\n 11 #因為服務端server3是根據行來讀取的 12 s.sendall("%s\r\n"%cmd) #把命令發送給服務端端 13 data=s.recv(1024) #把接收的數據定義為變量 14 print data #輸出變量 15 s.close() #關閉連接
依次啟動服務端和兩個客戶端,這個時候不論是在客戶端1還是客戶端2輸入,服務端都可以接收並反饋消息。
服務端控制臺打印(客戶端控制臺不展示了):1 begin... 2 receive from ((‘127.0.0.1‘, 10989)):‘def‘ 3 begin... 4 begin... 5 receive from ((‘127.0.0.1‘, 11015)):‘poi‘ 6 begin... 7 receive from ((‘127.0.0.1‘, 10989)):‘abc‘ 8 begin...
Python基礎筆記系列十三:socket網絡編程