• python学习笔记(socket模块)


    1、socket模块使用要分为服务端及客户端,服务端用于接收并处理请求,然后把请求数据回传回到客户端,客户端用于读取数据、关闭连接、最后结束交互

    2、服务端socket模块使用步骤:

          

     1 import socket
     2 
     3 phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
     4 phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)  #
     5 phone.bind(('127.0.0.1',8080))    #绑定(主机,端口号)到套接字
     6 
     7 phone.listen(5)    #开始TCP监听
     8 
     9 conn,client_addr=phone.accept()  #被动接受TCP客户的连接,(阻塞式)等待连接的到来
    10 
    11 client_data=conn.recv(1024)   # 接收TCP数据 最大1024字节
    12 conn.send(client_data.upper())   #发送TCP数据
    13 
    14 
    15 conn.close()     #关闭TCPl连接
    16 
    17 phone.close()    #关闭套接字
    View Code

    3、客户端socket模块使用步骤:

     1 import socket
     2 
     3 phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
     4 phone.connect(('127.0.0.1',8080))   #连接服务端的ip+port
     5 
     6 
     7 msg=input('>>:').strip()
     8 
     9 phone.send(msg.encode('utf-8'))   #向服务端发送信息
    10 server_data=phone.recv(1024)     #接收服务端的信息
    11 
    12 
    13 phone.close()   #关闭连接
    View Code

    4、socket模块是基于TCP或UDP协议实现的,由于TCP协议是流式数据,所以基于tcp协议的socket会出现粘包现象,解决粘包现象需要使用  struct模块。

          struct模块的用途:把一个类型,如数字,转成固定长度的bytes

                       使用方法:a=struct.pack('i',123123123123)   # 将123123123123装换成4个bytes长度;

                                        stauct.unpack('i',a)[0]     #提取123123123123

             详细类型转换如图:

            

        处理粘包问题:

              我们可以把报头做成字典,字典里包含将要发送的真实数据的详细信息,然后json序列化,然后用struck将序列化后的数据长度打包成4个字节(4个自己足够用了)

             发送时:先发报头长度

                          再编码报头内容然后发送

                          最后发真实内容

             接收时:先手报头长度,用struct取出来

                           根据取出的长度收取报头内容,然后解码,反序列化

                           从反序列化的结果中取出待取数据的详细信息,然后去取真实的数据内容

       

     1 import socket,struct,json
     2 import subprocess
     3 phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
     4 phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加
     5 
     6 phone.bind(('127.0.0.1',8080))
     7 
     8 phone.listen(5)
     9 
    10 while True:
    11     conn,addr=phone.accept()
    12     while True:
    13         cmd=conn.recv(1024)
    14         if not cmd:break
    15         print('cmd: %s' %cmd)
    16 
    17         res=subprocess.Popen(cmd.decode('utf-8'),
    18                              shell=True,
    19                              stdout=subprocess.PIPE,
    20                              stderr=subprocess.PIPE)
    21         err=res.stderr.read()
    22         print(err)
    23         if err:
    24             back_msg=err
    25         else:
    26             back_msg=res.stdout.read()
    27 
    28 
    29         conn.send(struct.pack('i',len(back_msg))) #先发back_msg的长度
    30         conn.sendall(back_msg) #在发真实的内容
    31 
    32     conn.close()
    33 
    34 服务端(自定制报头)
    服务端代码
     1 #_*_coding:utf-8_*_
     2 import socket,time,struct
     3 
     4 s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
     5 res=s.connect_ex(('127.0.0.1',8080))
     6 
     7 while True:
     8     msg=input('>>: ').strip()
     9     if len(msg) == 0:continue
    10     if msg == 'quit':break
    11 
    12     s.send(msg.encode('utf-8'))
    13 
    14 
    15 
    16     l=s.recv(4)
    17     x=struct.unpack('i',l)[0]
    18     print(type(x),x)
    19     # print(struct.unpack('I',l))
    20     r_s=0
    21     data=b''
    22     while r_s < x:
    23         r_d=s.recv(1024)
    24         data+=r_d
    25         r_s+=len(r_d)
    26 
    27     # print(data.decode('utf-8'))
    28     print(data.decode('gbk')) #windows默认gbk编码
    29 
    30 客户端(自定制报头)
    客户端代码

      

  • 相关阅读:
    The EF 6.x DbContextGenerator templates are not available for VS2010
    selenium定位tr及td,并获取其文本及属性
    selenium基本操作
    Git入门
    独热编码OneHotEncoder简介
    openCV中直方图均衡化算法的理解
    pyinstaller生成exe文件失败
    图像形态学运算
    对双边滤波的理解
    PyQt中对RadioButton分组
  • 原文地址:https://www.cnblogs.com/brightbrother/p/7412657.html
Copyright © 2020-2023  润新知