python-40-初識socket與struct

前言

網絡中進程間如何通訊?我怎麼找到某個電腦上的某個程序進行通訊呢?那麼利用三元組【ip地址,協議,端口】能夠進行網絡間通訊。shell

所以,Python中的socket模塊即可以使其進行通訊!可是通訊過程當中會出現黏包,Python中可使用struct模塊進行解決。服務器

1、socket 模塊

tcp是基於連接的,必須先啓動服務端,而後再啓動客戶端去連接服務端。網絡

兩個py文件之間進行通訊實例:socket

①基於TCP協議的sockettcp

server:服務端學習

import socket
sk=socket.socket()
sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sk.bind(('12.0.0.1',8080)) # 綁定服務端的:IP+端口
sk.listen()                       # 監聽鏈接
conn, addr = sk.accept()          # 接收鏈接 三次握手conn
lis=list(addr)
print('IP:%s 端口:%s 已請求鏈接!'%(lis[0],lis[1]))
while 1:
    res=conn.recv(1024).decode('utf-8')        # 接收信息
    print(res)
    if res=='886':break
    ret=input('美女>>>')
    if ret=='886':
        conn.send(bytes(ret.encode('utf-8')))  # 發送信息
    conn.send(bytes(ret.encode('utf-8')))      # 發送信息
conn.close()                                     # 關閉客戶端套接字
sk.close()                                       #關閉服務器套接字

②client:客戶端編碼

import socket
sk=socket.socket()                         # 建立客戶套接字
sk.connect(('127.0.0.1',8080))       # 嘗試鏈接服務端
while 1:
    ret=input('帥哥>>>')
    if ret=='886':
        sk.send(bytes(ret.encode('utf-8')))
        break
    sk.send(bytes(ret.encode('utf-8')))     # 發送信息
    msg=sk.recv(1024).decode('utf-8')       # 接收信息
    print(msg)
    if msg=='886':break
sk.close()                                   # 關閉客戶套接字

二、基於UDP協議的socketspa

udp是無連接的,啓動服務以後能夠直接接受消息,不須要提早創建連接。3d

①server:服務端code

# 二、基於UDP協議的socket
# udp是無連接的,啓動服務以後能夠直接接受消息,不須要提早創建連接
import socket
udp_sk = socket.socket(type=socket.SOCK_DGRAM)   # 建立一個服務器的套接字
udp_sk.bind(('127.0.0.1',8080))                  # 綁定服務器套接字
msg,addr = udp_sk.recvfrom(1024)
print(msg)
udp_sk.sendto(b'udp_server',addr)                # 對話(接收與發送)
udp_sk.close()                                   # 關閉服務器套接

②client:客戶端

import socket
ip_port=('127.0.0.1',8080)
udp_sk=socket.socket(type=socket.SOCK_DGRAM)
udp_sk.sendto(b'udp_client',ip_port)
back_msg,addr=udp_sk.recvfrom(1024)
print(back_msg.decode('utf-8'),addr)

三、長連接

①長連接:因同一時間只能一個程序連接,因此多個只會鏈接一個。

# 三、長連接
# 因同一時間只能一個程序連接,因此多個只會鏈接一個
import socket
sk=socket.socket()
sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sk.bind(('192.168.1.124',8080)) # 綁定服務端的:IP+端口
sk.listen()                       # 監聽鏈接
while 1:
    conn, addr = sk.accept()  # 接收鏈接 三次握手conn
    lis = list(addr)
    print('IP:%s 端口:%s 已請求鏈接!' % (lis[0], lis[1]))
    while 1:
        res = conn.recv(1024).decode('utf-8')  # 接收信息
        print(res)
        if res=='886':break
        ret=input('美女>>>')
        if ret=='886':
            conn.send(bytes(ret.encode('utf-8')))  # 發送信息
        conn.send(bytes(ret.encode('utf-8')))      # 發送信息
    conn.close()                                     # 關閉客戶端套接字

2、struct 模塊

基本思路:

  • 客戶端傳輸的內容,len長度
  • 將長度通過struct成爲4位字節碼
  • 服務端解4位字節碼,就知道了文件的大小
  • 便開始傳輸

一、遠程Windows cmd命令實例:

①server:服務端

import socket,struct
sk=socket.socket()
sk.bind(('127.0.0.1',8888))
sk.listen()
conn,addr=sk.accept()
while 1:
    cmd=input('請輸入命令:')
    if cmd=='q':
        conn.send(b'q')
        break
    conn.send(cmd.encode('gbk'))     # win系統gbk編碼
    num=conn.recv(4)
    num=struct.unpack('i',num)[0]    # 將4個字節解碼轉爲原來的大小
    print(num)
    res=conn.recv(int(num)).decode('gbk')
    print(res)
conn.close()
sk.close()

②client:客戶端

import socket,subprocess,struct
sk=socket.socket()
sk.connect(('127.0.0.1',8888))

while 1:
    cmd=sk.recv(1024).decode('gbk')
    if cmd=='q':
        break
    res=subprocess.Popen(cmd,shell=True,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)
    std_out=res.stdout.read()
    std_err=res.stderr.read()
    len_num=len(std_out)+len(std_err)   # 長度
    num_by=struct.pack('i',len_num)     # struct處理後變爲4個字節
    sk.send(num_by)                      # 先發送處理後的長度,讓對方解字節
    sk.send(std_out)
    sk.send(std_err)
sk.close()

歡迎來你們QQ交流羣一塊兒學習:482713805

相關文章
相關標籤/搜索