Socket簡單實現ssh筆記

2022-01-14 21:35:40 字數 4183 閱讀 1181

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))

print

(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 與客戶端建立連線並進行通訊,原...