socket本質上就是在2臺網路互通的電腦之間,架設乙個通道,兩台電腦通過這個通道來實現資料的互相傳遞。 我們知道網路 通訊 都 是基於 ip+port 方能定位到目標的具體機器上的具體服務,作業系統有0-65535個埠,每個埠都可以獨立對外提供服務,如果 把乙個公司比做一台電腦 ,那公司的總機號碼就相當於ip位址, 每個員工的分機號就相當於埠, 你想找公司某個人,必須 先打**到總機,然後再轉分機 。 建立乙個socket必須至少有2端, 乙個服務端,乙個客戶端, 服務端被動等待並接收請求,客戶端主動發起請求, 連線建立之後,雙方可以互發資料。(利用ip和埠實現兩個裝置的通訊)。
接收端:import
socket
socket.tcp/ip
listen(ip,port)
waiting()
#等待資料
recv()#
接收資料
send()#
再傳送資料
傳送端:import
socket
socket.tcp/ip
connect(a.ip,a.port)
#接受端主機的ip,埠(port:埠號)
socket.send(hello)#
傳送的資料sendall()名義上是一次性傳送所有的資料,但是由於系統原因還是有限制的
socket.recv()#
接收資料
socket.close()#
關閉
伺服器端:import
socket
server=socket.socket()#
設定連線
server.bind((「localhost」,8888))#
繫結連線(引數是乙個元組)
server.listen(5)#
監聽conn,addr=server.accept()#
等待data=conn.recv(1024)#
接收(是byte型別的,需要轉換(一般編為utf-8))
conn.sendall(data)#
一次性傳送所有資料(由於系統原因,是傳送不了所有的資料的)
server.close()
客戶端:import
socket
client=socket.socket()
client=connect((「localhost」,8888))#
建立連線,引數是乙個元組
data=input().strip()#
手工輸入的是unicode型別,但是再傳輸的時候是要編碼的
client.send(data.encode(「utf-8」))#
傳送資料
data=client.recv(1024)#
收到的資料是utf-8編碼的,所以直接輸出是亂碼
client.close()
當你連續的呼叫send()時,由於接收時recv()有大小限制,會發生傳送的資料量大於接收的資料量,導致接收的資料不是你期待的資料,這個時候就發生了粘包(兩次傳送的資料被同一次接收) 為了避免這種錯誤,我們通常會設計反饋,即你傳送一次資料,我們會吧傳送的資料反饋給傳送給你。這樣兩次傳送中間夾雜著一次接收,避免了資料在緩衝中導致粘包。
我們在python3中,預設是unicode,而在傳送資料(send)時,函式send()的引數型別是:byte,所以我們要進行資料的轉換:
str==>bytes
bytes==>str
a=」qweqwe」 =>a的型別為str
str==>bytes
b=a.encode(「utf-8」)
b=b」hello word」 =>b為bytes型別
bytes==>str
s=b.decode(「utf-8」)
字串型別的,我們可以利用hashlib包中的md5演算法來檢驗
檔案型別的,我們可以對比兩個檔案的區別:
diff file1 file2
觀察兩個檔案是否一致(檔案檢測)
這個比較方便,它整合了一些東西,很方便的,只是server端改變了一下書寫方式,客戶端不用改變
**如下:
#this is server
import
socketserver
class mytcphandler(socketserver.baserequesthandler):#
類名隨意,但是繼承的不能改變
def handle(self):#
系統會自動呼叫這個函式,我們只需要在這個函式中寫我們要實現的方法就可以了
while
true:
try:
self.data=self.request.recv(1024).strip()
print("
{} wrote
".format(self.client_address))
(self.data)
self.request.send(self.data.upper())
except
connectionreseterror as e:
print("
error:
",e)
break
if__name__ =="
__main__":
host,port="
localhost
",9999#
宣告ip與埠
server=socketserver.threadingtcpserver((host,port),mytcphandler)#
設定連線
server.serve_forever()#
建立連線,然後系統在連線成功以後會自動呼叫函式handle()
#this is client
import
socket
client=socket.socket()
client.connect((
"localhost
",9999))
while
true:
cmd=input("
>>
").strip()
if cmd ==""
:
continue
client.send(cmd.encode())
data=client.recv(1024)
print(data)
附:socket乙個最簡單的通訊:
#伺服器端:
import
socket
server=socket.socket()
server.bind((
"localhost
",8888))
server.listen()
conn,addr=server.accept()
count=10
while
count:
data=conn.recv(1024)
print(data.decode("
utf-8"))
conn.send(data)
count-=1server.close()
#客戶端import
socket
client=socket.socket()
client.connect((
"localhost
",8888))
while
true:
chioce=input("
>>
").strip()
client.sendall(chioce.encode(
"utf-8"))
data=client.recv(1024)
ifnot
data:
break
print(data.decode("
utf-8"))
client.close()
php簡單實現socket通訊
socket通訊的原理在這裡就不說了,它的用途還是比較廣泛的,我們可以使用 socket 來做乙個 api介面出來,也可以使用 socket 來實現兩個程式之間的通訊,我們來研究一下在 php開發 中如何實現socket通訊。由於socket服務端的 要監聽埠,等待接收請求,所以 php在做 soc...
epoll實現簡單socket通訊
epoll是常用的socket通訊方式,相比於select和poll來說,效率提公升了不止一點半點 其一 select中socket描述符 檔案描述符 集的資料結構為陣列,poll的檔案描述符集資料結構為鍊錶,無論陣列還是鍊錶,它們都是線性結構,當遍歷時,也只能線性遍歷 而epoll檔案描述符集採用...
Socket筆記和簡單例項
socket的通訊過程 伺服器端 01,申請乙個socket 02,繫結到乙個ip位址和乙個埠上 03,開啟偵聽,等待接收連線 客戶端 01,申請乙個socket 02,連線伺服器 指明ip位址和埠號 伺服器端接收到連線請求後,產生乙個新的socket 埠大於1024 與客戶端建立連線並進行通訊,原...