day26html
網絡通訊shell
參考:網絡
http://www.cnblogs.com/yuanchenqi/articles/5692716.htmlsocket
男生是client端,字條是socket(sk),經過sk通訊。url
socket屬於客戶端。應用程序兩端經過「套接字」向網絡發出請求或者應答網絡請求。能夠把socket理解爲通訊的把手(hand)。spa
肯定對端IP地址→ 肯定應用程序端口 → 肯定通信協議.net
server下的方法命令行
bind()code
listen()server
accept()
recv()
send()#傳送內容必須爲bytes類型
sendall()
close()
client下的方法
connect()
recv()
send()
aendall()
close()
client發送,serve接收
serve.py
1 import socket 2 3 sk = socket.socket()#建立socket 4 5 print(sk) 6 7 address = ('127.0.0.1', 8000)#本機地址 8 sk.bind(address)#爲socket綁定IP和端口號 9 10 sk.listen(3)#限制排隊的個數 11 print('waiting......') 12 conn, addr = sk.accept()#conn爲客戶端socket對象 13 # 14 # inp = input('>>>') 15 # conn.send(bytes(inp, 'utf8')) 16 17 data = conn.recv(1024)#爲何用conn,而不用sk 18 print(str(data, 'utf8')) 19 20 # conn.close()#關具體對象 21 # sk.close()#全關
client.py
1 import socket 2 3 sk = socket.socket() 4 5 print(sk) 6 address = ('127.0.0.1', 8000) 7 8 sk.connect(address) 9 10 #data = sk.recv(1024)#收到的爲bytes類型 11 data = sk.send(bytes('hah', 'utf8')) 12 13 #print(str(data, 'utf8'))
運行serve.py
<socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('0.0.0.0', 0)> waiting......
waiting,accept()阻塞。
運行client.py
<socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('0.0.0.0', 0)> Process finished with exit code 0
serve收到數據「hah」
<socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('0.0.0.0', 0)> waiting...... hah Process finished with exit code 0
client接收,serve發送
serve.py
1 import socket 2 3 sk = socket.socket()#建立socket 4 5 print(sk) 6 7 address = ('127.0.0.1', 8000)#本機地址 8 sk.bind(address)#爲socket綁定IP和端口號 9 10 sk.listen(3)#限制排隊的個數 11 print('waiting......') 12 conn, addr = sk.accept()#conn爲客戶端socket對象 13 14 inp = input('>>>') 15 conn.send(bytes(inp, 'utf8')) 16 17 # data = conn.recv(1024)#爲何用conn,而不用sk 18 # print(str(data, 'utf8')) 19 20 # conn.close()#關具體對象 21 # sk.close()#全關
client.py
import socket sk = socket.socket() print(sk) address = ('127.0.0.1', 8000) sk.connect(address) data = sk.recv(1024)#收到的爲bytes類型 #data = sk.send(bytes('hah', 'utf8')) print(str(data, 'utf8'))
運行serve.py
<socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('0.0.0.0', 0)> waiting......
運行client.py
<socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('0.0.0.0', 0)>
在serve命令行輸入hello
<socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('0.0.0.0', 0)> waiting...... >>>hello Process finished with exit code 0
client命令行收到數據。
<socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('0.0.0.0', 0)> hello Process finished with exit code 0
不間斷聊天
client.py
1 import socket 2 3 sk = socket.socket() 4 5 print(sk) 6 address = ('127.0.0.1', 8000) 7 sk.connect(address) 8 9 while True: 10 inp = input('>>>') 11 if inp == 'exit': 12 break 13 sk.send(bytes(inp, 'utf8')) 14 15 data = sk.recv(1024) 16 print(str(data, 'utf8')) 17 18 sk.close() 19 #print(sk)
serve.py
1 import socket 2 3 sk = socket.socket()#建立socket 4 5 print(sk) 6 7 address = ('127.0.0.1', 8000)#本機地址 8 sk.bind(address)#爲socket綁定IP和端口號 9 10 sk.listen(3)#限制排隊的個數 11 print('waiting......') 12 #conn, addr = sk.accept()#conn爲客戶端socket對象 13 14 while True: 15 conn, addr = sk.accept() 16 print(addr) #client打開則接收 17 while True: 18 #收 19 try: 20 data = conn.recv(1024)#爲何用conn,而不用sk,client關閉時報錯誤 21 except Exception: 22 break #client端中止,他也中止 23 print('.......',str(data, 'utf8')) 24 if not data:break 25 #發 26 inp = input('>>>') 27 conn.send(bytes(inp, 'utf8')) 28 29 sk.close()#全關
不間斷聊天,其中client若關閉,新開一個client,serve端還能繼續服務。
粘包現象(遠程執行命令)
cmd_client.py
1 import socket 2 3 sk = socket.socket() 4 5 print(sk) 6 address = ('127.0.0.1', 8001) 7 sk.connect(address) 8 9 while True: 10 inp = input('>>>') 11 if inp == 'exit': 12 break 13 sk.send(bytes(inp, 'utf8')) 14 result_len = int(str(sk.recv(1024), 'utf8')) 15 16 sk.sendall(bytes('ok', 'utf8'))#收到長度信息後,告訴server 17 18 data = bytes()#初始化 19 while len(data) != result_len: #等於原文件大小,說明接收完 20 recv = sk.recv(1024) 21 data += recv 22 23 print(str(data, 'utf8')) 24 25 sk.close() 26 #print(sk)
cmd_server.py
1 import socket 2 import subprocess 3 sk = socket.socket()#建立socket 4 5 print(sk) 6 7 address = ('127.0.0.1', 8001)#本機地址 8 sk.bind(address)#爲socket綁定IP和端口號 9 10 sk.listen(3)#限制排隊的個數 11 print('waiting......') 12 #conn, addr = sk.accept()#conn爲客戶端socket對象 13 14 while True: 15 conn, addr = sk.accept() 16 print(addr) #client打開則接收 17 while True: 18 #收 19 try: 20 data = conn.recv(1024)#爲何用conn,而不用sk,client關閉時報錯誤 21 except Exception: 22 break #client端中止,他也中止 23 print('.......',str(data, 'utf8')) 24 25 if not data:break 26 obj = subprocess.Popen(str(data, 'utf8'), shell = True, stdout = subprocess.PIPE) 27 cmd_result = obj.stdout.read()#以上執行結果 28 #print(cmd_result) 29 result_len = bytes(str(len(cmd_result)), 'utf8') 30 31 32 conn.sendall(result_len)#發 33 #先向client發送數據,client若收到則向server發送OK,Server再發送處理結果 34 #若連續發送,兩個發送內容(長度,處理結果)可能會合並。 35 re = conn.recv(1024)#防止粘包 36 if str(re, 'utf8') != 'ok': 37 break 38 #發 39 conn.sendall(cmd_result) 40 41 # conn.sendall(result_len) # 這種方式會發生粘包現象,長度和內容合在一塊兒了 42 # conn.sendall(cmd_result) 43 sk.close()#全關
先執行server.py,再執行client.py,在client中輸入命令(dir,pwd,ifconfig等)