① 請教如何使用python的socket發送二進制數據
socket發送的本來就是按二進制發送,你是想把數據打包成str用socket發出去吧?
可以用struct來打包
import struct
data = struct.pack('i', 123)
然後用socket發送就行了,這里打包一個整數的例子,struct很強大可以網路一下具體用法。
② 請教如何使用python的socket發送二進制數據
客戶端clt.py
#coding:utf8
importsocket
HOST='192.168.1.101'
PORT=12008
defsend_data(data):
try:
sock_clt=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock_clt.connect((HOST,PORT))
sock_clt.send(data)
finally:
sock_clt.close()
whileTrue:
send_data('你的二進制數據')
服務端svr.py
#coding:utf8
importsocket
HOST=''
PORT=12008
SIZE=4096
sock_svr=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#pythonsocketserver重啟後,埠被佔用的解決方法
sock_svr.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sock_svr.bind((HOST,PORT))
sock_svr.listen(1)
whileTrue:
print"waitingoftheclienttoconnect"
clt_conn_sock,addr=sock_svr.accept()
print'Connectedby',addr
comp_data=''
whileTrue:
data=clt_conn_sock.recv(SIZE)
ifnotdata:
break
comp_data+=data
clt_conn_sock.close()
ifnotcomp_data:
continue
printcomp_data
服務端可以使用socket的select或poll,也可以使用twisted
③ python 用socket怎麼發送一段二進制數據
參考python 的struct mole — Interpret strings as packed binary data, 用來將數據封裝到類似C語言的結構體中進行發送。具體可以參考:
https://docs.python.org/2/library/struct.html
http://www.cnblogs.com/gala/archive/2011/09/22/2184801.html
http://stackoverflow.com/questions/3753589/packing-and-unpacking-variable-length-array-string-using-the-struct-mole-in-py
④ 在python中如何從二進制文件中讀取信息
你是指讀入二進制文件吧?
可以使用numpy.fromfile(),也可以使用open(filename, 'rb'),其中的'b'就是二進制的意思,然後使用文件類型的read方法,讀取一些位元組,再用struct.unpack()方法來解析二進制。
第一種方法是一次性讀入文件(或文件的前多少個連續位元組)到一個數組中,因此,靈活性差。
第二種方法靈活性很高,可以讀取任意位置(使用文件的seek()方法跳躍位置)的二進制數據,再使用struct.unpack()方法來進行各種二進制解析。
提示:二進制文件是不保留存儲方式的數據格式,因此,讀二進制文件時應該知道二進制文件的存儲格式。
⑤ 如何用python獲取websocket數據
這里,介紹如何使用 Python 與前端 js 進行通信。
websocket 使用 HTTP 協議完成握手之後,不通過 HTTP 直接進行 websocket 通信。
於是,使用 websocket 大致兩個步驟:使用 HTTP 握手,通信。
js 處理 websocket 要使用 ws 模塊; python 處理則使用 socket 模塊建立 TCP 連接即可,比一般的 socket ,只多一個握手以及數據處理的步驟。
握手
過程
包格式
js 客戶端先向伺服器端 python 發送握手包,格式如下:
?
1
2
3
4
5
6
7
8
GET
/chat HTTP/1.1
Host:
server.example.com
Upgrade:
websocket
Connection:
Upgrade
Sec-WebSocket-Key:
dGhlIHNhbXBsZSBub25jZQ==
Origin:
Sec-WebSocket-Protocol:
chat, superchat
Sec-WebSocket-Version:
13
伺服器回應包格式:
?
1
2
3
4
5
HTTP/1.1
101 Switching Protocols
Upgrade:
websocket
Connection:
Upgrade
Sec-WebSocket-Accept:
s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol:
chat
其中, Sec-WebSocket-Key 是隨機的,伺服器用這些數據構造一個 SHA-1 信息摘要。
方法為: key+migic , SHA-1 加密, base-64 加密,如下:
Python 中的處理代碼
?
1
2
MAGIC_STRING='258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
res_key=base64.b64encode(hashlib.sha1(sec_key
+MAGIC_STRING).digest())
握手完整代碼
js 端
js 中有處理 websocket 的類,初始化後自動發送握手包,如下:
var socket = new WebSocket('ws://localhost:3368');
Python 端
Python 用 socket 接受得到握手字元串,處理後發送
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
HOST='localhost'
PORT=3368
MAGIC_STRING='258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
HANDSHAKE_STRING="HTTP/1.1
101 Switching Protocols\r\n"
\
"Upgrade:websocket\r\n"\
"Connection:
Upgrade\r\n"
\
"Sec-WebSocket-Accept:
{1}\r\n"
\
"WebSocket-Location:ws://{2}/chat\r\n"
\
"WebSocket-Protocol:chat\r\n\r\n"
defhandshake(con):
#con為用socket,accept()得到的socket
headers={}
shake=con.recv(1024)
ifnot
len(shake):
returnFalse
header,
data =shake.split('\r\n\r\n',1)
forline
inheader.split('\r\n')[1:]:
key,
val =line.split(':
',1)
headers[key]=val
if'Sec-WebSocket-Key'
not
in
headers:
print('This
socket is not websocket, client close.')
con.close()
returnFalse
sec_key=headers['Sec-WebSocket-Key']
res_key=base64.b64encode(hashlib.sha1(sec_key
+MAGIC_STRING).digest())
str_handshake=HANDSHAKE_STRING.replace('{1}',
res_key).replace('{2}',
HOST +':'
+
str(PORT))
printstr_handshake
con.send(str_handshake)
returnTrue
通信
不同版本的瀏覽器定義的數據幀格式不同, Python 發送和接收時都要處理得到符合格式的數據包,才能通信。
Python 接收
Python 接收到瀏覽器發來的數據,要解析後才能得到其中的有用數據。
瀏覽器包格式
固定位元組:
( 1000 0001 或是 1000 0002 )這里沒用,忽略
包長度位元組:
第一位肯定是 1 ,忽略。剩下 7 個位可以得到一個整數 (0 ~ 127) ,其中
( 1-125 )表此位元組為長度位元組,大小即為長度;
(126)表接下來的兩個位元組才是長度;
(127)表接下來的八個位元組才是長度;
用這種變長的方式表示數據長度,節省數據位。
mark 掩碼:
mark 掩碼為包長之後的 4 個位元組,之後的兄弟數據要與 mark 掩碼做運算才能得到真實的數據。
兄弟數據:
得到真實數據的方法:將兄弟數據的每一位 x ,和掩碼的第 i%4 位做 xor 運算,其中 i 是 x 在兄弟數據中的索引。
完整代碼
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
defrecv_data(self,
num):
try:
all_data=self.con.recv(num)
ifnot
len(all_data):
returnFalse
except:
returnFalse
else:
code_len=ord(all_data[1])
& 127
ifcode_len
==126:
masks=all_data[4:8]
data=all_data[8:]
elifcode_len
==127:
masks=all_data[10:14]
data=all_data[14:]
else:
masks=all_data[2:6]
data=all_data[6:]
raw_str=""
i=0
ford
indata:
raw_str+=chr(ord(d)
^ ord(masks[i%4]))
i+=1
returnraw_str
js 端的 ws 對象,通過 ws.send(str) 即可發送
ws.send(str)
Python 發送
Python 要包數據發送,也需要處理,發送包格式如下
固定位元組:固定的 1000 0001( 『 \x81 ′ )
包長:根據發送數據長度是否超過 125 , 0xFFFF(65535) 來生成 1 個或 3 個或 9 個位元組,來代表數據長度。
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
defsend_data(self,
data):
ifdata:
data=str(data)
else:
returnFalse
token="\x81"
length=len(data)
iflength
< 126:
token+=struct.pack("B",
length)
eliflength
<=0xFFFF:
token+=struct.pack("!BH",126,
length)
else:
token+=struct.pack("!BQ",127,
length)
#struct為Python中處理二進制數的模塊,二進制流為C,或網路流的形式。
data='%s%s'
%
(token, data)
self.con.send(data)
returnTrue
js 端通過回調函數 ws.onmessage() 接受數據
?
1
2
3
4
5
ws.onmessage
= function(result,nTime){
alert("從服務端收到的數據:");
alert("最近一次發送數據到現在接收一共使用時間:"+
nTime);
console.log(result);
}
最終代碼
Python服務端
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#
_*_ coding:utf-8 _*_
__author__='Patrick'
importsocket
importthreading
importsys
importos
importMySQLdb
importbase64
importhashlib
importstruct
#
====== config ======
HOST='localhost'
PORT=3368
MAGIC_STRING='258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
HANDSHAKE_STRING="HTTP/1.1
101 Switching Protocols\r\n"
\
"Upgrade:websocket\r\n"\
"Connection:
Upgrade\r\n"
\
"Sec-WebSocket-Accept:
{1}\r\n"
\
"WebSocket-Location:ws://{2}/chat\r\n"
\
"WebSocket-Protocol:chat\r\n\r\n"
classTh(threading.Thread):
def__init__(self,
connection,):
threading.Thread.__init__(self)
self.con=connection
defrun(self):
whileTrue:
try:
pass
self.con.close()
defrecv_data(self,
num):
try:
all_data=self.con.recv(num)
ifnot
len(all_data):
returnFalse
except:
returnFalse
else:
code_len=ord(all_data[1])
& 127
ifcode_len
==126:
masks=all_data[4:8]
data=all_data[8:]
elifcode_len
==127:
masks=all_data[10:14]
data=all_data[14:]
else:
masks=all_data[2:6]
data=all_data[6:]
raw_str=""
i=0
ford
indata:
raw_str+=chr(ord(d)
^ ord(masks[i%4]))
i+=1
returnraw_str
#
send data
defsend_data(self,
data):
ifdata:
data=str(data)
else:
returnFalse
token="\x81"
length=len(data)
iflength
< 126:
token+=struct.pack("B",
length)
eliflength
<=0xFFFF:
token+=struct.pack("!BH",126,
length)
else:
token+=struct.pack("!BQ",127,
length)
#struct為Python中處理二進制數的模塊,二進制流為C,或網路流的形式。
data='%s%s'
%
(token, data)
self.con.send(data)
returnTrue
#
handshake
defhandshake(con):
headers={}
shake=con.recv(1024)
ifnot
len(shake):
returnFalse
header,
data =shake.split('\r\n\r\n',1)
forline
inheader.split('\r\n')[1:]:
key,
val =line.split(':
',1)
headers[key]=val
if'Sec-WebSocket-Key'
not
in
headers:
print('This
socket is not websocket, client close.')
con.close()
returnFalse
sec_key=headers['Sec-WebSocket-Key']
res_key=base64.b64encode(hashlib.sha1(sec_key
+MAGIC_STRING).digest())
str_handshake=HANDSHAKE_STRING.replace('{1}',
res_key).replace('{2}',
HOST +':'
+
str(PORT))
printstr_handshake
con.send(str_handshake)
returnTrue
defnew_service():
"""start
a service socket and listen
when
coms a connection, start a new thread to handle it"""
sock=socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
try:
sock.bind(('localhost',3368))
sock.listen(1000)
#鏈接隊列大小
print"bind
3368,ready to use"
except:
print("Server
is already running,quit")
sys.exit()
whileTrue:
connection,
address =sock.accept()
#返回元組(socket,add),accept調用時會進入waite狀態
print"Got
connection from ",
address
ifhandshake(connection):
print"handshake
success"
try:
t=Th(connection,
layout)
t.start()
print'new
thread for client ...'
except:
print'start
new thread error'
connection.close()
if__name__
=='__main__':
new_service()
js客戶 端
?
1
2
3
4
5
6
7
8
<script>
varsocket
= newWebSocket('ws://localhost:3368');
ws.onmessage
= function(result,nTime){
alert("從服務端收到的數據:");
alert("最近一次發送數據到現在接收一共使用時間:"+
nTime);
console.log(result);
}
</script>
⑥ 請問下python網路編程的位元組序怎麼處理
多謝樓上的,不是這么處理的python發送的都是二進制的string串,對數字類型的數據可以使用struct模塊來實現,具體例子如下:struct.pack('>l',
3)這里是輸出一個整數3,>表示使用網路位元組序,l表示數據類型
⑦ Python中b101011是合法的二進制數值表示形式
是的,是 Python 中有效的二進制數表示形式。在 Python 中,二進制數使用前綴後跟一系列 and 數字來表示。例如,二進制數可以像在 Python 中一樣寫。b1010110b011010110b101011
下面是在 Python 中使用前綴定義二進制數的示例:0b
回答不易望請採納
⑧ 求助:python如何按位解析二進制數據
可以的,二進制是計算機內的表示方法,處理二進制數據是最基本的能力。
如果是二進制字元串轉十進制:
>>>x='10101010'
>>>int(x,2)
170
如果是從文件或網路中獲取的數據,要知道某一位是0還是1的話,獲取的數據可以按字元讀取,由於一個字元由8位二進製表示,分別讀取1到8位的二進制值就可以了:
>>>get_char_bit=lambdachar,n:(char>>(8-n))&1#從高到低分別為第1~8位
>>>data=b'ab'#在python3中字元串默認是unicode,所以加上b前綴兼容
>>>#在python3中按字元讀取byte字元串是數字,而python2讀出來的卻是字元,但bytearray是一致的都是數字
>>>data=bytearray(data)
>>>result=[]
>>>forcharindata:
foriinrange(1,9):
result.append(get_char_bit(char,i))
>>>result
[0,1,1,0,0,0,0,1,0,1,1,0,0,0,1,0]
還有一種比較簡單的方法是使用內置的bin函數
>>>data=bytearray(b'ab')
>>>result=[]
>>>forcharindata:
result.extend(bin(char)[2:].rjust(8,'0'))
>>>result
['0','1','1','0','0','0','0','1','0','1','1','0','0','0','1','0']
⑨ 如何用Python將十進制數字轉為二進制,以及將二進制轉為十六進制
1、將十進制轉換成二進制,利用bin()方法。