Socket簡單實現ssh筆記


 

  1. Scoket概念:

    socket本質上就是在2台網絡互通的電腦之間,架設一個通道,兩台電腦通過這個通道來實現數據的互相傳遞。 我們知道網絡 通信 都 是基於 ip+port 方能定位到目標的具體機器上的具體服務,操作系統有0-65535個端口,每個端口都可以獨立對外提供服務,如果 把一個公司比做一台電腦 ,那公司的總機號碼就相當於ip地址, 每個員工的分機號就相當於端口, 你想找公司某個人,必須 先打電話到總機,然后再轉分機 。 建立一個socket必須至少有2端, 一個服務端,一個客戶端, 服務端被動等待並接收請求,客戶端主動發起請求, 連接建立之后,雙方可以互發數據。(利用IP和端口實現兩個設備的通信)。
  2. Socket核心方法:

    接收端:
    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()#關閉
  3. 實例列舉:

    服務器端:
    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()





  4. 粘包:

    當你連續的調用send()時,由於接收時recv()有大小限制,會發生發送的數據量大於接收的數據量,導致接收的數據不是你期待的數據,這個時候就發生了粘包(兩次發送的數據被同一次接收) 為了避免這種錯誤,我們通常會設計反饋,即你發送一次數據,我們會吧發送的數據反饋給發送給你。這樣兩次發送中間夾雜着一次接收,避免了數據在緩沖中導致粘包。
  5. 一些注意的地方:

  • 發送與接收的類型:

         我們在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

觀察兩個文件是否一致(文件檢測)

SocketServer:

這個比較方便,它集成了一些東西,很方便的,只是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-=1
server.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)
    if not data:
        break
    print(data.decode("utf-8"))
client.close()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM