python-40-初识socket与struct

前言

网络中进程间如何通信?我怎么找到某个电脑上的某个程序进行通信呢?那么利用三元组【ip地址,协议,端口】可以进行网络间通信。

因此,Python中的socket模块便可以使其进行通信!但是通信过程中会出现黏包,Python中可以使用struct模块进行解决。

一、socket 模块

tcp是基于链接的,必须先启动服务端,然后再启动客户端去链接服务端。

两个py文件之间进行通信实例:

①基于TCP协议的socket

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()                                   # 关闭客户套接字

2、基于UDP协议的socket

udp是无链接的,启动服务之后可以直接接受消息,不需要提前建立链接。

①server:服务端

# 2、基于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)

3、长链接

①长链接:因同一时间只能一个程序链接,所以多个只会连接一个。

# 3、长链接
# 因同一时间只能一个程序链接,所以多个只会连接一个
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()                                     # 关闭客户端套接字

二、struct 模块

基本思路:

  • 客户端传输的内容,len长度
  • 将长度经过struct成为4位字节码
  • 服务端解4位字节码,就知道了文件的大小
  • 便开始传输

1、远程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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

姚二龙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值