9.2 Socket編程
遠程管理軟件和黑客軟件大多依賴於Socket來實現特定功能,前幾年流行的端口反彈更是把這項技術發揮到了極致。
如前所述,UDP和TCP是網絡體系結構的傳輸層運行的兩大重要協議,其中,TCP適用於對效率要求相對低而準確性要求相對高的場合,如文本傳輸、電子郵件等;而UDP適用於對效率要求相對高,對準確性要求相對低的場合,如視頻在線點播、網絡語音通話等。在Python中,主要使用socket模塊來支持TCP和UDP編程。
9.2.1 UDP編程
在很多年以前普通家庭還沒有手機、電話、傳呼機的時候,主要靠信件往來聯系,發信人提哦啊好收信人地址然後把信件寄出去就可以了,但是沒法保證對方一定能收到這封信(例如對方換了地址),也不能保證不同時間的幾封信按照發出的順序到達目的地。UDP的工作過程就類似於郵寄普通信件,它屬於無連接協議,在UDP編程時不需要首先建立連接,而是直接向接收方發送信息。UDP也不提供應答和重傳機制,無法保證數據一定鞥能夠到達目的地。UDP最大的優點是效率高,其首部中只包含雙發地址於校驗等很少的字段,額外開銷很小。UDP編程經常用到的socket模塊方法如下。
(1)socket([family[,type[,proto]]] :創建一個Socket對象,其中family為socket.AF_INET表示IPv4,AF_INET6表示IPv6;type為SOCK_STREAM表示使用TCP,SOCK_DGRAM表示使用UDP。
(2)sendto(string,address):把string指定的內容發送給address指定的地址,其中address是一個包含接收方主機IP地址的應用進程端號的元組,格式為(IP地址,端口號)。
(3)recvfrom(bufsize[,flags]):接收數據。
下面通過一個示例來簡單了解一個如何使用UDP進行網絡通信。
發送端發送一個字符串,假設接收端在本機5000端口進行監聽,並顯示接受的內容,如果收到字符串‘bye‘(忽略大小寫)則結束監聽。
接收端代碼:
1 import socket
2
3 #使用IPv4協議,使用UDP傳輸數據
4 s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
5
6 #綁定端口和端口好,空字符串表示本機任何可用IP地址
7 s.bind(‘‘,5000)
8
9 while True:
10 data,addr = s.recvfrom(1024)
11
12 #顯示接收到的內容
13 print(‘received message:{0} from PORT{1} on {2}‘.format(data.decode(),addr[1],addr[0]))
14
15 if data.decode().lower() == ‘bye‘:
16 break
17
18 s.close()
發送端代碼:
import socket
import sys
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#假設192.168.1.103是接收端機器的IP地址
s.sendto(sys.argv[1].encode(),(‘192.168.1.103‘,5000))
s.close()
將上面的代碼分別保存為receiver.py和sender.py,然後首先啟動一個命令提示符環境並運行接收端程序,這時接收端程序處於阻塞狀態,接下來再啟動一個新的命令體書法環境並運行發送端程序,此時會看到接收端程序繼續運行並顯示接收到的內容以及發送端程序所在計算機IP地址和占用的端口號。當發送端發送字符串‘bye‘後,接收單程序結束,此後再次運行發送端程序時接收端沒有任何反應,但發送端程序也並不報錯。這就是UDP的特點,即“盡最大努力傳輸”,並不能保證非常好的服務質量。
可以使用下面的Python代碼來獲取本機的IP地址和網卡的物理地址。
1 ip = socket.gethostbyname(socket.gethostname()) #本機IP地址
2 node = uuid.getnode()
3 print(‘node:‘,node)
4
5 macHex = uuid.UUID(int=node).hex[-12:]
6 mac = []
7 print(macHex)
8 for i in range(len(macHex))[::2]:
9 mac.append(macHex[i:i+2])
10
11 mac1 = ‘:‘.join(mac) #網卡的物理地址
12
13 print(‘IP:‘,ip)
14 print(‘MAC:‘,mac1)
拓展知識:發送數據時,如果目標IP地址中最後一組數字是255,表示廣播地址,也就是說局域網內的所有主機都會受到信息。
9.2 Socket編程