首页 > 编程语言 >Python学习笔记--网络通信--socket

Python学习笔记--网络通信--socket

时间:2023-02-24 16:55:12浏览次数:58  
标签:socket phone -- AF Python print data conn

1.socket里面的,AF_INET和AF_UNIX有什么区别?

 

 2.socket 通信示例?

  • 服务端:
    • 代码:
    • import socket
      
      # 1.买手机
      phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
          # AF_INET和AF_UNIX区别,AF_INET远程交互,AF_UNIX本地交互
          # SOCK_STREAM 流式协议 = TCP ; SOCK_DGRAM 数据报协议 = UDP
      
      print(phone)   # <socket.socket fd=436, family=AddressFamily.AF_INET, type=SocketKind.SOCK_DGRAM, proto=0>
      
      # 2.绑定电话卡
      phone.bind(("127.0.0.1",8080))  # 绑定ip和端口 # 为了让客户端访问,这里一般固定后就不变了.
      
      # 3.开机
      phone.listen(5) # __backlog = 5 半连接池数量为5
      
      # 4.接受链接信息
      conn,client_addr = phone.accept()   # 返回两个值. conn是链接通路,是三次握手的成果;client_addr是客户端的地址.
      print(conn)
      #<socket.socket fd=356, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0,
      # laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 1873)>
      print(client_addr)
      # ('127.0.0.1', 1873)
      
      # 5.收发消息
      data = conn.recv(1024) # 最大接收字节数 1024 ; 注意 这里的data是byte类型
      print(data) # b'hello'
      conn.send(data.upper()) # 回消息 ,这里为了演示,把data的大写返回去。
      
      # 6.挂电话
      conn.close()
      
      # 7.关机
      phone.close()

       

  •  客户端:
    • 代码:
    • import socket
      
      # 1.买手机
      phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
          # AF_INET和AF_UNIX区别,AF_INET远程交互,AF_UNIX本地交互
          # SOCK_STREAM 流式协议 = TCP ; SOCK_DGRAM 数据报协议 = UDP
      
      # 2. 打电话
      phone.connect(("127.0.0.1",8080))
      
      
      # 3.发,收数据
      phone.send("hello".encode("utf-8"))
      # phone.send(b"hello") # 这样也可以
      
      data = phone.recv(1024) # 接收数据 同样设置为1024
      print(data.decode("utf-8")) # 返回的也是byte类型,需要解码
      
      
      # 4.关机
      phone.close()

       

 3.socket通信,升级--加上循环。

  • 服务端:
    • import socket
      
      # 1.买手机
      phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      
      # 2.绑定电话卡
      phone.bind(("127.0.0.1",8080))
      
      # 3.开机
      phone.listen(5)
      
      # 4.接受链接信息
      conn,client_addr = phone.accept()   # 返回两个值. conn是链接通路,是三次握手的成果;client_addr是客户端的地址.
      
      # 5.收发消息
      while True:
          data = conn.recv(1024) # 最大接收字节数 1024 ; 注意 这里的data是byte类型
          print(data) # b'hello'
          conn.send(data.upper()) # 回消息 ,这里为了演示,把data的大写返回去。
      
      # 6.挂电话
      conn.close()
      
      # 7.关机
      phone.close()

       

  • 客户端:
    • import socket
      
      # 1.买手机
      phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
          # AF_INET和AF_UNIX区别,AF_INET远程交互,AF_UNIX本地交互
          # SOCK_STREAM 流式协议 = TCP ; SOCK_DGRAM 数据报协议 = UDP
      
      # 2. 打电话
      phone.connect(("127.0.0.1",8080))
      
      
      # 3.发,收数据
      # 建立循环
      while True:
          msg = input("请输入信息:")
          phone.send(msg.encode("utf-8"))
      
          data = phone.recv(1024) # 接收数据 同样设置为1024
          print(data.decode("utf-8")) # 返回的也是byte类型,需要解码
      
      
      # 4.关机
      phone.close()

       

4.socket通信--升级2--解决客户端发空报错。

  • 服务端代码不动:
    • import socket
      
      # 1.买手机
      phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      
      # 2.绑定电话卡
      phone.bind(("127.0.0.1",8080))
      
      # 3.开机
      phone.listen(5)
      
      # 4.接受链接信息
      conn,client_addr = phone.accept()   # 返回两个值. conn是链接通路,是三次握手的成果;client_addr是客户端的地址.
      
      # 5.收发消息
      while True:
          data = conn.recv(1024) # 最大接收字节数 1024 ; 注意 这里的data是byte类型
          print(data) # b'hello'
          conn.send(data.upper()) # 回消息 ,这里为了演示,把data的大写返回去。
      
      # 6.挂电话
      conn.close()
      
      # 7.关机
      phone.close()

       

  •  客户端--增加为空判断
    • import socket
      
      # 1.买手机
      phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      
      # 2. 打电话
      phone.connect(("127.0.0.1", 8080))
      
      # 3.发,收数据
      # 建立循环
      while True:
          msg = input("请输入信息:")
          if len(msg) == 0:
              continue  # 跳过本次
          phone.send(msg.encode("utf-8"))
          # print("1111111111") 调试1
          data = phone.recv(1024)  # 接收数据  # 发空消息,会阻塞这里
          # print("222222222") 调试2
          print(data.decode("utf-8"))
      
      # 4.关机
      phone.close()

       

5.服务端,应该具备的能力是?

  • 一直提供服务
  • 并发的能力

 

6.socket通信--升级3--解决服务端一直接受“空”问题。

  • 服务端:
    • 增加长度判断
    • 代码:
    • import socket
      
      # 1.买手机
      phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      
      # 2.绑定电话卡
      phone.bind(("127.0.0.1",8080))
      
      # 3.开机
      phone.listen(5)
      
      # 4.接受链接信息
      conn,client_addr = phone.accept()   # 返回两个值. conn是链接通路,是三次握手的成果;client_addr是客户端的地址.
      
      # 5.收发消息
      while True:
          try:    # win 其他版本, 会报错
              data = conn.recv(1024)
              if len(data) == 0:  # linux win11 会收到空 b''
                  break
              print(data) # b'hello'
              conn.send(data.upper())
          except Exception:
              break
      
      # 6.挂电话
      conn.close()
      
      # 7.关机
      phone.close()

 

 

 

  • 客户端:
    • import socket
      
      # 1.买手机
      phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      
      # 2. 打电话
      phone.connect(("127.0.0.1", 8080))
      
      # 3.发,收数据
      # 建立循环
      while True:
          msg = input("请输入信息:")
          if len(msg) == 0:
              continue  # 跳过本次
          phone.send(msg.encode("utf-8"))
          # print("1111111111") 调试1
          data = phone.recv(1024)  # 接收数据  # 发空消息,会阻塞这里
          # print("222222222") 调试2
          print(data.decode("utf-8"))
      
      # 4.关机
      phone.close()

       

7.socket通信--升级4--解决服务端只能提供一次服务。

  • 想让服务端一直提供服务。
  • 服务端:
    • 增加循环。
    • import socket
      
      # 1.买手机
      phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      
      # 2.绑定电话卡
      phone.bind(("127.0.0.1", 8080))
      
      # 3.开机
      phone.listen(5)
      
      # 4.接受链接信息
      # 循环执行
      while True:
          conn, client_addr = phone.accept()
      
          # 5.收发消息
          while True:
              try:  # win 其他版本, 会报错
                  data = conn.recv(1024)
                  if len(data) == 0:  # linux win11 会收到空 b''
                      break
                  print(data)  # b'hello'
                  conn.send(data.upper())
              except Exception:
                  break
      
          # 6.挂电话
          conn.close()
      
      # 7.关机
      phone.close()

       

  • 客户端:
    • 代码:
    • import socket
      
      # 1.买手机
      phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      
      # 2. 打电话
      phone.connect(("127.0.0.1", 8080))
      
      # 3.发,收数据
      # 建立循环
      while True:
          msg = input("请输入信息:")
          if len(msg) == 0:
              continue  # 跳过本次
          phone.send(msg.encode("utf-8"))
          # print("1111111111") 调试1
          data = phone.recv(1024)  # 接收数据  # 发空消息,会阻塞这里
          # print("222222222") 调试2
          print(data.decode("utf-8"))
      
      # 4.关机
      phone.close()

       

8.如何写一个执行远程命令的C/S程序?

  • 服务端--调用subprocess来执行
  • import socket
    import subprocess
    # 1.买手机
    phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
    # 2.绑定电话卡
    phone.bind(("127.0.0.1", 8080))
    
    # 3.开机
    phone.listen(5)
    
    # 4.接受链接信息
    # 循环执行
    while True:
        conn, client_addr = phone.accept()
    
        # 5.收发消息
        while True:
            try:  # win 其他版本, 会报错
                cmd = conn.recv(1024)
                if len(cmd) == 0:  # linux win11 会收到空 b''
                    break
                cmd = cmd.decode("utf-8")   # 先解码
                # 再执行
                obj = subprocess.Popen(cmd,shell=True,
                                       stderr=subprocess.PIPE,
                                       stdout=subprocess.PIPE
                                       )
                res1 = obj.stdout.read()
                res2 = obj.stderr.read()
                conn.send(res1+res2)    # 把两个值都返回去
            except Exception:
                break
    
        # 6.挂电话
        conn.close()
    
    # 7.关机
    phone.close()

     

  • 客户端--注意解码方式(win用gbk,linux用utf-8)
  • import socket
    
    # 1.买手机
    phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
    # 2. 打电话
    phone.connect(("127.0.0.1", 8080))
    
    # 3.发,收数据
    # 建立循环
    while True:
        msg = input("请输入信息:")
        if len(msg) == 0:
            continue  # 跳过本次
        phone.send(msg.encode("utf-8"))
        data = phone.recv(1024)  # 接收数据  # 发空消息,会阻塞这里
        print(data.decode("gbk"))   # 在win解码用gbk
    
    # 4.关机
    phone.close()
    
    # !!!注意,这里输入tasklist会出现不全。输入dir可以展示

     

  • 问题1,是输入tasklist会出现显示不全的现象。
  • 问题2,是输入tasklist后再输入dir会发现显示的上次剩余的内容。(这可以帮助理解【流协议】)
  • 我的解决:可以尝试recv(1024) -->recv(更大的数字)

 

 

 

 

 

 

 

 

 

 

 

 

 

参考资料:

标签:socket,phone,--,AF,Python,print,data,conn
From: https://www.cnblogs.com/liqi175/p/17152125.html

相关文章

  • eclipse链接gitee
    Eclipse链接gitee(通过SSH)创建gitee账号进入gitee官网工作台-Gitee.com(2)点击注册填写相关信息(3)创建仓库填入相关信息在eclipse上适配gitee环境生成密钥(2)在eclipse窗口......
  • 不相关子查询
    ​ 【1】什么是子查询?一条SQL语句含有多个select, --引入子查询:--查询所有比“CLARK”工资高的员工的信息--步骤1:“CLARK”工资selectsalfromempwheree......
  • Centos 7 安装Netbox
    #####installpostgresql##############sudoyuminstall-yhttps://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.r......
  • 不相关子查询
    ​ 【1】什么是子查询?一条SQL语句含有多个select, --引入子查询:--查询所有比“CLARK”工资高的员工的信息--步骤1:“CLARK”工资selectsalfromempwheree......
  • JDBC
    快速入门在模块下新建lib文件夹,将mysql的jar包粘贴进去并右键选择添加为库,范围选择模块库packagejdbc;importjava.sql.Connection;importjava.sql.DriverManager......
  • ArcGIS10.4授权文件 32/64位使用方法
    ArcGIS10.4授权文件是一款针对同名软件《ArcGIS10.4》所推出的序列号激活码生成工具。通过使用这款授权文件,你就可以进行注册激活,永久免费使用该软件1、安装桌面并按照正......
  • P6666 [清华集训2016] 数据交互 题解
    ##P6666[清华集训2016]数据交互题解###简要题意:n个点的树,m次操作,分别为添加一条路径$(u_i,v_i,w_i)$,和撤消一条路径,每一次操作后求出一条路径使得与这条路径有交的......
  • yoloV2
    引用:https://zhuanlan.zhihu.com/p/35325884https://blog.csdn.net/qq_40716944/article/details/1148225151.1BatchNormalization在YOLOv2中,每个卷积层后面都添加......
  • uni-app:微信小程序:分享给微信好友和分享到朋友圈(hbuilderx 3.7.3)
    一,代码:<template><view><viewstyle="margin-left:20rpx;margin-top:20rpx;width:710rpx;height:710rpx;background:gray;"><imageclass="b......
  • 使用函数-单行函数
    ​ 使用函数-单行函数 2.数值函数(Math)    3.日期与时间函数         --单行函数包含:--1.字符串函数selectename,length(ena......