用socket和線程實現全雙工收發數據
1.基礎知識
Socket(套接字) |
網絡上的兩個程序通過一個雙向的通信連接實現數據的交換,這個連接的一端稱為一個socket。由此知道套接字是全雙工的。 |
線程(thread) |
線程是操作系統能夠進行運算調度的最小單位。它被包含在進程之中,是進程中的實際運作單位。一條線程指的是進程中一個單一順序的控制流,一個進程中可以並發多個線程,每條線程並行執行不同的任務。 |
- 什么是單工,全雙工,半雙工?
全雙工:是指在發送數據的同時也能夠接收數據,兩者同步進行,這好像我們平時打電話一樣,說話的同時也能夠聽到對方的聲音。
半雙工:在一段時間內,只有一種動作發生,例如一條窄路,而只有一輛車可以通行,當有兩輛車相對通行時,只有一輛車先通過,另一頭的那輛車的才能通過。隨着技術的不斷進步,半雙工將會退出歷史舞台,例子:對講機。
單工:全雙工和半雙工都是雙向通信,而單工是單向通信,在同一時間只有一方能接受或發送信息,例子:電視,廣播。
全雙工 |
雙向 |
可同時發送接受數據 |
電話通信 |
半雙工 |
雙向 |
不可同時發送接受數據 |
對講機 |
單工 |
單向 |
不可同時發送接受數據 |
電視,廣播 |
2.代碼
import socket import threading def send_msg(udp_socket, dest_ip, dest_port): """發送消息""" # 獲取要發送的內容 while True: send_data = input("請輸入要發送的消息:") udp_socket.sendto(send_data.encode("gbk"), (dest_ip, dest_port)) def recv_msg(udp_socket,): """接收數據""" while True: recv_data = udp_socket.recvfrom(1024) print("\n收到了消息%s:%s" % (str(recv_data[1]), recv_data[0].decode("gbk"))) def main(): # 1.創建套接字,AF_INET表示面向網絡的,UDP的套接字名字是SOCK_DGRAM udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 2.綁定本機ip和端口:第一個參數為空則默認綁定本機ip,第二個參數填寫端口號 udp_socket.bind(("", 7788)) # 3.指定對方ip dest_ip = input("請輸入對方的ip:") dest_port = int(input("請輸入對方的port:")) # 4.創建線程並運行:args需要一個元組參數 ts = threading.Thread(target=send_msg, args=(udp_socket, dest_ip, dest_port)) tr = threading.Thread(target=recv_msg, args=(udp_socket,)) ts.start() tr.start() if __name__ == "__main__": main()
3.運行
運行前准備工作,准備兩台電腦,一台運行程序(以下稱A電腦),另一台(以下稱B)用mNetAssist(網絡調式助手,下載鏈接: https://pan.baidu.com/s/1Sq1SvqJnxbijrx4kSYbc1g 提取碼: 1f8b)測試程序。Windows下打開cmd用ipcongfig查詢ip(linux下用ifconfig查詢),查詢結果如下:A電腦ip為172.16.86.21,B電腦的ip為172.17.189.148。然后將B電腦的mNetAssist設置配置如下
接下來運行程序,輸入B電腦的IP及端口號,然后互發消息,運行結果如下: