本文目錄一覽:
用python篡改icmp報文再發送給接收方
程序處理上有些問題,建議深入研究一下ICMP協議。下面是Python 3的一個ICMP的簡單實現,可以參考一下。
import socket
import struct
def checksum(source_string):
sum = 0
countTo = (len(source_string)/2)*2
count = 0
while countcountTo:
thisVal = ord(source_string[count + 1:count + 2])*256 + ord(source_string[count:count + 1])
sum = sum + thisVal
sum = sum 0xffffffff
count = count + 2
if countTolen(source_string):
sum = sum + ord(source_string[len(source_string) – 1])
sum = sum 0xffffffff
sum = (sum 16) + (sum 0xffff)
sum = sum + (sum 16)
answer = ~sum
answer = answer 0xffff
answer = answer 8 | (answer 8 0xff00)
return answer
def ping(ip):
rawsocket1=socket.socket(socket.AF_INET,socket.SOCK_RAW, socket.getprotobyname(‘icmp’))
packet = struct.pack(‘!BBHHH8s’, 8, 0, 0, 0, 0, b’abcdefgh’)
chksum=checksum(packet)
packet = struct.pack(‘!BBHHH8s’, 8, 0, chksum, 0, 0, b’abcdefgh’)
rawsocket1.sendto(packet, (ip, 1))
ping(‘10.172.23.254’)
python基礎(21)-線程通信
到這裡,我們要聊一下線程通信的內容;
首先,我們拋開語言不談,先看看比較基礎的東西,線程間通信的方式;其實也就是哪幾種(我這裡說的,是我的所謂的知道的。。。)事件,消息隊列,信號量,條件變量(鎖算不算?我只是認為是同步的一種);所以我們也就是要把這些掌握了,因為各有各的好處嘛;
條件變量我放到了上面的線程同步裏面講了,我總感覺這算是同步的一種,沒有很多具體信息的溝通;同時吧,我認為條件變量比較重要,因為這種可以應用於線程池的操作上;所以比較重要;這裡,拋開條件變量不談,我們看看其他的東西;
1、消息隊列:
queue 模塊下提供了幾個阻塞隊列,這些隊列主要用於實現線程通信。在 queue 模塊下主要提供了三個類,分別代表三種隊列,它們的主要區別就在於進隊列、出隊列的不同。
關於這三個隊列類的簡單介紹如下:
queue.Queue(maxsize=0):代表 FIFO(先進先出)的常規隊列,maxsize 可以限制隊列的大小。如果隊列的大小達到隊列的上限,就會加鎖,再次加入元素時就會被阻塞,直到隊列中的元素被消費。如果將 maxsize 設置為 0 或負數,則該隊列的大小就是無限制的。
queue.LifoQueue(maxsize=0):代表 LIFO(後進先出)的隊列,與 Queue 的區別就是出隊列的順序不同。
PriorityQueue(maxsize=0):代表優先級隊列,優先級最小的元素先出隊列。
這三個隊列類的屬性和方法基本相同, 它們都提供了如下屬性和方法:
Queue.qsize():返回隊列的實際大小,也就是該隊列中包含幾個元素。
Queue.empty():判斷隊列是否為空。
Queue.full():判斷隊列是否已滿。
Queue.put(item, block=True, timeout=None):向隊列中放入元素。如果隊列己滿,且 block 參數為 True(阻塞),當前線程被阻塞,timeout 指定阻塞時間,如果將 timeout 設置為 None,則代表一直阻塞,直到該隊列的元素被消費;如果隊列己滿,且 block 參數為 False(不阻塞),則直接引發 queue.FULL 異常。
Queue.put_nowait(item):向隊列中放入元素,不阻塞。相當於在上一個方法中將 block 參數設置為 False。
Queue.get(item, block=True, timeout=None):從隊列中取出元素(消費元素)。如果隊列已滿,且 block 參數為 True(阻塞),當前線程被阻塞,timeout 指定阻塞時間,如果將 timeout 設置為 None,則代表一直阻塞,直到有元素被放入隊列中; 如果隊列己空,且 block 參數為 False(不阻塞),則直接引發 queue.EMPTY 異常。
Queue.get_nowait(item):從隊列中取出元素,不阻塞。相當於在上一個方法中將 block 參數設置為 False。
其實我們想想,這個隊列,是python進行封裝的,那麼我們可以用在線程間的通信;同時也是可以用做一個數據結構;先進先出就是隊列,後進先出就是棧;我們用這個棧寫個十進制轉二進制的例子:
沒毛病,可以正常的打印;其中需要注意的就是,maxsize在初始化的時候如果是0或者是個負數的話,那麼就會是不限制大小;
那麼其實我們想想,我們如果用做線程通信的話,我們兩個線程,可以把隊列設置為1的大小,如果是1對多,比如是創建者和消費者的關係,我們完全可以作為消息隊列,比如說創建者一直在創建一些東西,然後放入到消息隊列裏面,然後供消費着使用;就是一個很好的例子;所以,其實說是消息隊列,也就是隊列,沒差;
=====================================================================
下面來看一下事件
Event 是一種非常簡單的線程通信機制,一個線程發出一個 Event,另一個線程可通過該 Event 被觸發。
Event 本身管理一個內部旗標,程序可以通過 Event 的 set() 方法將該旗標設置為 True,也可以調用 clear() 方法將該旗標設置為 False。程序可以調用 wait() 方法來阻塞當前線程,直到 Event 的內部旗標被設置為 True。
Event 提供了如下方法:
is_set():該方法返回 Event 的內部旗標是否為True。
set():該方法將會把 Event 的內部旗標設置為 True,並喚醒所有處於等待狀態的線程。
clear():該方法將 Event 的內部旗標設置為 False,通常接下來會調用 wait() 方法來阻塞當前線程。
wait(timeout=None):該方法會阻塞當前線程。
這裡我想解釋一下;其實對於事件來說,事件可以看成和條件變量是一樣的,只是我們說說不一樣的地方;
1、對於事件來說,一旦觸發了事件,也就是說,一旦set為true了,那麼就會一直為true,需要clear調內部的標誌,才能繼續wait;但是conditon不是,他是一次性的喚醒其他線程;
2、conditon自己帶鎖;事件呢?不是的;沒有自己的鎖;比如說有一個存錢的線程,有一個是取錢的線程;那麼存錢的線程要存錢;需要怎麼辦呢?1、發現銀行沒有錢了(is_set判斷);2、鎖住銀行;3、存錢;4、釋放銀行;5、喚醒事件;對於取錢的人;1、判斷是否有錢;2、被喚醒了,然後鎖住銀行;3、開始取錢;4、清理告訴存錢的人,我沒錢了(clear);5、釋放鎖;6、等着錢存進去;
其實說白了,就是記住一點;這個旗標需要自己clear就對了
寫個例子,怕以後忘了怎麼用;
其實時間和信號量比較像;但是信號量不用自己清除標誌位;但是事件是需要的;
如何用python實現串口通信
Python非常適合寫一些測試的腳本,如快速的串口通信測試等。如果使用VC++ QT開發,可能用時較多,使用python,如果掌握使用方法,可以直接讀寫測試,配合設備或是串口助手,很快驗證與實現。
Python有沒有現成的串口API直接調用呢?經過實踐驗證,需要安裝一個叫 Pyserial的組件即可。這個可以在github上下載。
在windows 7 64bit 上可以使用嗎?當然可以使用,我安裝的python3.5為64位的。把下載後的文件,其中有一個serial的文件夾,拷貝到python35安裝路徑, C:\Python35\Lib\site-packages\serial
網上可以搜一下windows的安裝包,安裝完也是:C:\Python35\Lib\site-packages\serial ,可以用最新的版本,替換即可。
測試的方法:在python IDE里測試:
import serial
這裡如果報錯,是python版本與pyserial版本沒有配合好。如果正常,不返回,即可以導入serial模塊。
ser=serial.Serial(“COM5”,115200)
這裡為COM5,115200的波特率。如果打不開,請檢查安裝環境。
ser.write(‘hello,serial test’.encode())
17
發送測試(如果返回位元組數,說明返回成功),這裡需要轉換一個編碼為位元組。
以上測試,可以使用現在的設備或是串口助手,如安裝Virtual Serial Port Driver 7.2 虛擬串口軟件,設置一對串口,進行自發自收的測試。
print(ser.readline())
b’abcdefg\r\n’
這裡是串口接收,有接收的超時。設備或是串口助手發送一個字符串,以回車換行結束,這裡就可以收到打印出來。
也可以用ser.read(),這裡只接收一個字符來實現。
上面已經實現了基本的串口操作。
關閉串口為:
ser.close()
如果使用python,一般寫個py文件,就像windows bat 批處理一樣,這是python強大的地方。如果寫一個py腳本呢?其實只要把上面的命令,一條條寫下來,就是一個腳本,測試如下:
import serialser=serial.Serial(“COM5”,115200,timeout=0.5)for i in range(0,100-1):ser.write(‘hello\r\n’.encode())print(ser.readline());ser.close()
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/241268.html