1. 程式人生 > >Python基礎筆記系列十三:socket網絡編程

Python基礎筆記系列十三:socket網絡編程

forever %s 如果 主機名 關閉連接 try 控制臺 utf-8 target

  本系列教程供個人學習筆記使用,如果您要瀏覽可能需要其它編程語言基礎(如C語言),why?因為我寫得爛啊,只有我自己看得懂!!
使用python編寫一個簡易的服務端程序和客戶端程序,啟動服務端和客戶端(監聽的ip和端口一致),服務端對客戶端進行指定Ip和端口的監聽,實現接收客戶端發送的數據以及對客戶端發送數據。

  • 使用原生socket
    主要運用到python的socket模塊,直接使用自己的代碼進行socket對象的創建、ip和端口的綁定、接收和發送數據等操作。
    服務端:server1.py
     1 #incoding:utf-8
     2 
     3 #下面這個例子是直接用socket來編程
     4 #server1 :
    5 from socket import * 6 myhost=127.0.0.1 7 myport=8080 8 sockobj = socket(AF_INET,SOCK_STREAM) #socket(ip協議,tcp協議) 9 sockobj.bind((myhost,myport)) #綁定ip和端口 10 sockobj.listen(128) #同時允許128個連接 11 while True: #註意True首字母大寫,當然也可以寫while 1: 12 connection,address = sockobj.accept() #accept()返回兩個值,一個連接對象,一個地址
    13 print connect by,address #打印連接這個服務的地址 14 while True: 15 data = connection.recv(1024) #把接收的數據實例化 16 print 客戶端發送過來的數據:+data#打印一下數據 17 connection.send(yours data: + data) #回顯數據,返回給客戶端 18 connection.close() #關閉連接

    客戶端:client1.py

     1 #incoding:utf-8
     2 #server1的客戶端程序
    3 #借鑒:https://blog.csdn.net/rebelqsp/article/details/22109925 4 from socket import * 5 HOST=127.0.0.1 6 PORT=8080 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 s.send(cmd) #把命令發送給服務端端 12 # print help(s) 13 data=s.recv(1024) #把接收的數據定義為變量 14 print data #輸出變量 15 s.close() #關閉連接

    寫好服務端和客戶端程序,現在進行測試。
    首先啟動服務端進行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.py
     1 #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)):‘1232 receive from ((‘127.0.0.1‘, 10458)):‘4563 receive from ((‘127.0.0.1‘, 10458)):‘abc‘
  • 多線程TCPServer
    上面的兩種方式都只支持一個客戶端和一個服務端進行通信,如果需要多個客戶端和一個服務端通信就需要用到ThreadingTCPServer,StreamRequestHandler,我們自己的類MyStreamRequestHandler從StreamRequestHandler繼承,並重寫handle方法,然後可以很簡單的就可以接收發送數據。
    服務端:server3.py
     1 #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網絡編程