前言:
你會發現會網絡是多么幸福的事情
主要內容:
socket 概念:
socket本質上就是2台網絡互通的電腦之間,架設一個通道,兩台電腦通過這個通道來實現數據的互相傳遞。我們知道網絡通信都是基於IP地址加短褲的方法來定位到目標的具體機器上的具體服務。操作系統有0-65535個端口,每個端口都可以獨立對外提供服務,如果把一個公司比做一台電腦,那公司的總機號碼就相當於IP地址,每個員工的分機號就相當於短褲,你想找公司某個人,必須先打電話到總機,然后再轉分機。
這里提到了OSI七層模型的概念:
第一層:物理層
第二層:數據鏈路層
第三層: 網絡層
第四層:傳輸層
第五層:會話層
第六層:表示層
第七層:應用層
建立一個socket必須至少有2端,1個是服務端,1個是客戶端,服務端被動等待並接受請求,客戶端主動發起請求,連接建立之后,雙方可以互發數據。
建立一個鏈接,需要IPV4和IPV6
Socket Types
socket.SOCK_STREAM #for tcp
socket.SOCK_DGRAM #for udp
socket.SOCK_RAW #原始套接字
建立鏈接之后,就需要IP和端口了
排隊數量,一般是5
sk.listen(backlog)
關閉套接字
sk.close()
接受套接字的數據
sk.recv(bufsize[,flag])
具體步驟
1、生成一個socket實例
server = socket.socket(AF_INET,SOCK_STREAM)
2、綁定地址
server.bind('0.0.0.0',8000)
3、監聽端口排隊5個
server.listen(5)
4、接受
talk_list = []
server.accept() 會返回2個值 conn 建立鏈接的線 client_addr 鏈接對象
talk_list.append(conn)
conn.send('sdfds')
另外一個介入進來
conn.recv('sdfsf')
5、發送
server.send()
6、關機
server.close()
上面是服務端
客戶端通信
client = socket.socket(AF_INET,SOCK_STREAM)
client.connect('')
client.send
client.recv
接下來,就通過代碼來實現這個服務端和客戶端
server端
#!/usr/bin/env python # -*- coding: utf-8 -*- #Author: Leon xie import socket server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) server.bind(("0.0.0.0",8000)) server.listen(5) conn,client_addr = server.accept() print(conn,client_addr) while True: data = conn.recv(1024) #1024字節 print("recv from cli:",data) conn.send(b"got it")
client端
#!/usr/bin/env python # -*- coding: utf-8 -*- #Author: Leon xie import socket client = socket.socket() client.connect(("localhost",8000)) while True: msg = input(">>:").strip() if len(msg) == 0:continue client.send(msg.encode()) print("send ",msg) data = client.recv(1024) print("receive from server:",data)
再開一個client的時候,會出現堵死的情況,斷開一個,另外一個可以使用了。
所以上面的可以改良
server端
#!/usr/bin/env python # -*- coding: utf-8 -*- #Author: Leon xie import socket server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) server.bind(("0.0.0.0",8000)) server.listen(5) while True: conn,client_addr = server.accept() print(conn,client_addr) while True: try: data = conn.recv(1024) #1024字節 print("recv from cli:",data) conn.send(b"got it") except ConnectionResetError as e: print(e) break
客戶端
#!/usr/bin/env python # -*- coding: utf-8 -*- #Author: Leon xie import socket client = socket.socket() client.connect(("localhost",8000)) while True: msg = input(">>:").strip() if len(msg) == 0:continue client.send(msg.encode()) print("send ",msg) data = client.recv(1024) print("receive from server:",data)
接着寫一個SSH連過去,執行命令的服務端和客戶端
server端
#!/usr/bin/env python # -*- coding: utf-8 -*- #Author: Leon xie import socket import subprocess server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) server.bind(("0.0.0.0",8000)) server.listen(5) print("=============start to listen============") while True: conn,client_addr = server.accept() print(conn,client_addr) while True: data = conn.recv(1024) #1024字節 print("recv from cli:",data) res_obj = subprocess.Popen(data,shell=True ,stdout=subprocess.PIPE,stderr=subprocess.PIPE) res = res_obj.stdout.read() conn.send(str(len(res)).encode()) print("==res len:",len(res)) conn.send(res)
客戶端
#!/usr/bin/env python # -*- coding: utf-8 -*- #Author: Leon xie import socket client = socket.socket() client.connect(("localhost",8000)) while True: msg = input(">>:").strip() if len(msg) == 0:continue client.send(msg.encode()) print("send ",msg) data = client.recv(1024) print("res:",data.decode()) res_len = int(data.decode()) recevied_size = 0 res = b'' while recevied_size < total_size: d = client.recv(1024) res += d recevied_size += len(d) print(res.decode())
最后做一個持續接受的server端和client端
服務端
[root@docker20-127 ~]# cat server.py #!/usr/bin/env python # -*- coding: utf-8 -*- #Author: Leon xie import socket import subprocess server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) server.bind(("0.0.0.0",8007)) server.listen(5) print("--------------start to listen------------------") while True: conn,client_addr = server.accept() print(conn,client_addr) while True: data = conn.recv(1024) print("recv from cli:",data) res_obj = subprocess.Popen(data,shell=True, stdout=subprocess.PIPE,stderr=subprocess.PIPE) res = res_obj.stdout.read() conn.send(str(len(res)).encode()) print("--res len:",len(res)) conn.send(res)
客戶端
#!/usr/bin/env python # -*- coding: utf-8 -*- #Author: Leon xie import socket client = socket.socket() client.connect(("10.10.20.127",8005)) while True: msg = input(">>:").strip() if len(msg) == 0:continue client.send(msg.encode()) print("send",msg) data = client.recv(1024) print("res:",data.decode()) total_size = int(data.decode()) #總長度跟已經收到的相等即可 received_size = 0 res=b'' while received_size <total_size: d = client.recv(1024) res += d received_size += len(d) print("---------------rece done------------") print(res.decode())
完結。
