客戶端python
import socket # 一、買手機 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 二、打電話 phone.connect(("127.0.0.1", 8080)) # phone至關於服務端的conn # 三、發、收消息 phone.send('hello'.encode("utf-8")) data = phone.recv(1024) print(data) # 四、關閉 phone.close()
服務端linux
import socket # 一、買手機 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 二、綁定手機卡 phone.bind(("127.0.0.1", 8080)) # 127.0.0.1本地地址,端口範圍0-65535:其中0-1024給操做系統使用 # 三、開機 phone.listen(5) # 5表明最大掛起鏈接數 # 四、等電話鏈接 print("starting...") conn, client = phone.accept() # 五、收、發消息 data = conn.recv(1024) # 收1024個字節,接受數據的最大數。單位是bytes print("客戶端的數據", data) conn.send(data.upper()) # 六、掛電話 conn.close() # 七、關機 phone.close()
客戶端shell
import socket # 一、買手機 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 二、打電話 phone.connect(("127.0.0.1", 8080)) # phone至關於服務端的conn # 三、發、收消息 while True: msg = input(">> ").strip() phone.send(msg.encode("utf-8")) data = phone.recv(1024) print(data) # 四、關閉 phone.close()
服務端windows
import socket # 一、買手機 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 二、綁定手機卡 phone.bind(("127.0.0.1", 8080)) # 127.0.0.1本地地址,端口範圍0-65535:其中0-1024給操做系統使用 # 三、開機 phone.listen(5) # 5表明最大掛起鏈接數 # 四、等電話鏈接 print("starting...") conn, client = phone.accept() # 五、收、發消息 while True: data = conn.recv(1024) # 收1024個字節,接受數據的最大數。單位是bytes print("客戶端的數據", data) conn.send(data.upper()) # 六、掛電話 conn.close() # 七、關機 phone.close()
一、客戶端單方面斷開,服務端: linux 解決辦法:if not data:break
windows 解決辦法:try...except
send 能夠發 空 # 發給了os的內存 在調用網卡 發送數據
recv 不能夠 收空 # 到了os的內存 在傳給了應用程序內存
因此 客戶端 就卡住了 if not msg:continue 卡住緣由 os 不會發''(空)數據cookie
二、端口已存在,重用ssh
問題:socket
這個是因爲你的服務端仍然存在四次揮手的time_wait狀態在佔用地址tcp
解決辦法1:優化
#加入一條socket配置,重用ip和端口
phone=socket(AF_INET,SOCK_STREAM)
phone.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #就是它,在bind前加
phone.bind(('127.0.0.1',8080))spa
解決辦法2:
發現系統存在大量TIME_WAIT狀態的鏈接,經過調整linux內核參數解決,
vi /etc/sysctl.conf
編輯文件,加入如下內容:
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30
而後執行 /sbin/sysctl -p 讓參數生效。
net.ipv4.tcp_syncookies = 1 表示開啓SYN Cookies。當出現SYN等待隊列溢出時,啓用cookies來處理,可防範少許SYN攻擊,默認爲0,表示關閉;
net.ipv4.tcp_tw_reuse = 1 表示開啓重用。容許將TIME-WAIT sockets從新用於新的TCP鏈接,默認爲0,表示關閉;
net.ipv4.tcp_tw_recycle = 1 表示開啓TCP鏈接中TIME-WAIT sockets的快速回收,默認爲0,表示關閉。
net.ipv4.tcp_fin_timeout 修改系統默認的 TIMEOUT 時間
解決辦法3:
解決前面啓動多個socket程序,佔用系統端口問題。(命令提示符cmd)
linux: pkill -9 python
windows: taskkill python (打開任務管理器,找到python,關閉)
客戶端
import socket # 一、買手機 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 二、打電話 phone.connect(("127.0.0.1", 8080)) # phone至關於服務端的conn # 三、發、收消息 while True: msg = input(">> ").strip() if not msg: continue phone.send(msg.encode("utf-8")) data = phone.recv(1024) print(data.decode("utf-8")) # 四、關閉 phone.close()
服務端
import socket # 一、買手機 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # (若是機器中存在,從新用端口)應對端口占用報錯狀況 # 二、綁定手機卡 phone.bind(("127.0.0.1", 8080)) # 127.0.0.1本地地址,端口範圍0-65535:其中0-1024給操做系統使用 # 三、開機 phone.listen(5) # 5表明最大掛起鏈接數 # 四、等電話鏈接 print("starting...") conn, client = phone.accept() # conn套接字對象 # 五、收、發消息 while True: try: data = conn.recv(1024) # 收1024個字節,接受數據的最大數。單位是bytes # if not data: break # 僅適用於Linux操做系統(客戶端單方面斷開),win 用try...except print("客戶端的數據", data) conn.send(data.upper()) except ConnectionRefusedError: break # 六、掛電話 conn.close() # 七、關機 phone.close()
服務端
import socket # 一、買手機 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # (若是機器中存在,從新用端口)應對端口占用報錯狀況 # 二、綁定手機卡 phone.bind(("127.0.0.1", 8080)) # 127.0.0.1本地地址,端口範圍0-65535:其中0-1024給操做系統使用 # 三、開機 phone.listen(5) # 5表明最大掛起鏈接數 # 四、等電話鏈接 print("starting...") while True: # 循環連接 conn, client = phone.accept() # conn套接字對象 # 五、收、發消息 while True: # 通信循環 try: data = conn.recv(1024) # 收1024個字節,接受數據的最大數。單位是bytes # if not data: break # 僅適用於Linux操做系統(客戶端斷開),win 用try...except print("客戶端的數據", data) conn.send(data.upper()) except ConnectionRefusedError: break # 六、掛電話 conn.close() # 七、關機 phone.close()
客戶端1
import socket # 一、買手機 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 二、打電話 phone.connect(("127.0.0.1", 8080)) # phone至關於服務端的conn # 三、發、收消息 while True: msg = input(">> ").strip() if not msg: continue phone.send(msg.encode("utf-8")) data = phone.recv(1024) print(data.decode("utf-8")) # 四、關閉 phone.close()
客戶端2
import socket # 一、買手機 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 二、打電話 phone.connect(("127.0.0.1", 8080)) # phone至關於服務端的conn # 三、發、收消息 while True: msg = input(">> ").strip() if not msg: continue phone.send(msg.encode("utf-8")) data = phone.recv(1024) print(data.decode("utf-8")) # 四、關閉 phone.close()
# windows
dir:查看某一個文件夾下的子文件名與文件夾名
ipconfig:查看本地網卡的ip信息
tasklist:查看運行的進程
# Linux
ls:查看某一個文件夾下的子文件名與文件夾名
ifconfig:查看本地網卡的ip信息(查看網卡的信息)
ps aux:查看運行的進程
在機器上執行系統命令
# import os
# res = os.system( ) # 只能拿到執行成功與否的標誌(0表明成功,非零表明不成功)
import subprocess
obj = subprocess.Popen("dir/",shell = True,stdout = subprocess.PIPE, stderr = subprocess.PIPE) #stdout命令正確結果
print("stdout", obj.stdout.read().decode("gbk")) # 打印出來結果(解碼linux:utf-8,windows:GBK)
print("stderr", obj.stderr.read().decode("gbk")) # 打印出來結果(解碼linux:utf-8,windows:GBK)
# import os # res = os.system('dir d:') # print(os.system('dir d:')) # # print(res) import subprocess obj=subprocess.Popen('dir d:ss',shell=True, stdout=subprocess.PIPE, # 正確的結果 stderr=subprocess.PIPE) # 錯誤的結果 print(obj) # 執行的結果 是bytes print('stdout 1--:',obj.stdout.read().decode('gbk')) # linux 是 utf-8 windows 是 gbk print('stdout 2--:',obj.stdout.read().decode('gbk')) # 由於管道沒有了 print('stdout 3--:',obj.stderr.read().decode('gbk')) # 錯誤管道里有 緣由 拿不到數據
服務端
import socket import subprocess # 一、買手機 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # (若是機器中存在,從新用端口)應對端口占用報錯狀況 # 二、綁定手機卡 phone.bind(("127.0.0.1", 9900)) # 127.0.0.1本地地址,端口範圍0-65535:其中0-1024給操做系統使用 # 三、開機 phone.listen(5) # 5表明最大掛起鏈接數 # 四、等電話鏈接 print("starting...") while True: # 循環連接 conn, client = phone.accept() # conn套接字對象 # 五、收、發消息 while True: # 通信循環 try: # a、接收命令 (命令:執行系統命令) cmd = conn.recv(1024) # 收1024個字節,接受數據的最大數。單位是bytes # if not data: break # 僅適用於Linux操做系統(客戶端斷開),win 用try...except # b、執行命令,拿到結果 obj = subprocess.Popen(cmd.decode("utf-8"), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout = obj.stdout.read() stderr = obj.stderr.read() # c、把命令的結果返回給客戶端 print(len(stdout)+len(stderr)) conn.send(stdout+stderr) # 加是從新申請了一塊內存地址,不是在原來地方變更(是一個能夠優化的點) except ConnectionRefusedError: break # 六、掛電話 conn.close() # 七、關機 phone.close()
客戶端
import socket # 一、買手機 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 二、打電話 phone.connect(("127.0.0.1", 9900)) # phone至關於服務端的conn # 三、發、收消息 while True: # a、發命令 cmd = input(">> ").strip() if not cmd: continue phone.send(cmd.encode("utf-8")) # b、拿命令結果並打印 data = phone.recv(1024) # 1024是個坑 print(data.decode("gbk")) # 系統發回的結果 # 四、關閉 phone.close()