socket淺析(二): 構建經過socket通訊的服務端和客戶端

socket服務端代碼:html

 

 1 import socket
 2 import os,subprocess
 3 
 4 
 5 server = socket.socket() #得到socket實例
 6 server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 7 
 8 ip_port = ('127.0.0.1', 10000) # 要綁定的IP及端口,元組數據形式
 9 
10 server.bind(ip_port) # 綁定ip port
11 server.listen()  # 開始監聽
12 
13 while True: # 第一層loop
14 
15     print("server is waiting...")
16     conn,addr = server.accept() # 接受並創建與客戶端的鏈接,程序在此處開始阻塞,只到有客戶端鏈接進來...
17     print("Connected by :",addr ) # 打印出當前是誰連接了客戶端
18 
19     while True:
20         data = conn.recv(1024)
21         if not data:
22             print("客戶端斷開了...")
23             break # 這裏斷開就會再次回到第一次外層的loop
24 
25         print("收到要執行的命令:",data)
26         #res = os.popen(data.decode()).read() #py3 裏socket發送的只有bytes,os.popen又只能接受str,因此要decode一下
27         res = subprocess.Popen(data,shell=True,stdout=subprocess.PIPE).stdout.read() # 跟上面那條命令的效果是同樣的
28 
29         if len(res) == 0:
30             res = "cmd exec success,has not output!".encode("utf-8")
31 
32         conn.send(str(len(res)).encode("utf-8")) # 發送數據以前,先告訴客戶端要發多少數據給它
33         client_final_ack = conn.recv(1024) # 等待客戶端響應
34         if client_final_ack.decode() == int(len(res)): # 若是收到客戶端響應的標誌位和發送的標誌位相等,即表明客戶端已經準備好接收數據了
35             
36             print(type(res))
37             conn.sendall(res) #發送端也有最大數據量限制,因此這裏用sendall,至關於重複循環調用conn.send,直至數據發送完畢
38 
39 server.close()

 

 

socket客戶端代碼:shell

 

 1 import socket
 2 import sys
 3 
 4 client = socket.socket() # 實例化socket
 5 ip_port = ('127.0.0.1', 10000) # 要綁定的IP及端口,元組數據形式
 6 
 7 
 8 client.connect(ip_port)
 9 
10 while True:
11 
12     msg = input(">>:").strip() # 獲取客戶端的輸入信息並去除空格
13 
14     if len(msg) == 0:continue # 若是輸入爲空則繼續循環等待輸入
15 
16     client.send(msg.encode("utf-8"))  # 轉碼併發送給服務端
17 
18     res_return_size  = client.recv(1024) #接收這條命令執行結果的大小
19     print("getting cmd result , ", res_return_size)
20 
21     total_rece_size = int(res_return_size)
22     print("total size:",res_return_size)
23 
24     client.send(res_return_size.encode("utf-8"))
25     received_size = 0 #已接收到的數據
26     cmd_res = b''
27     f = open("test_copy.html","wb")#把接收到的結果存下來,一會看看收到的數據 對不對
28     while received_size != total_rece_size: #表明還沒收完
29         data = client.recv(1024)
30         received_size += len(data) #爲何不是直接1024,還判斷len幹嗎,注意,實際收到的data有可能比1024少
31         cmd_res += data
32     else:
33         print("數據收完了",received_size)
34         #print(cmd_res.decode())
35         f.write(cmd_res) #把接收到的結果存下來,一會看看收到的數據 對不對
36         #print(data.decode()) #命令執行結果
37 
38 client.close()

 

程序缺限:

這是一個簡單的socket通訊,裏面存在一些bug多線程

1.在客戶端輸入回車,會掛死。併發

2.服務端返回的數據大於1024,客戶端顯示不全。socket

3.單進程,若是多個客戶端鏈接,要排隊,前一個斷開,後一個客戶端才能通訊。oop

先貼一個多線程的導圖:大數據

相關文章
相關標籤/搜索