网络编程 I(socket)

Posted xiaohei-chen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络编程 I(socket)相关的知识,希望对你有一定的参考价值。

1.今日内容

  1. socket套接字
  2. 基于TCP协议的socket通信
  3. 单个客户与服务端通信
  4. 通信循环
  5. 通信,连接循环
  6. 利用socket完成获取远端命令

2.具体内容

  1. socket套接字

  2. 基于TCP协议的socket通信

    • socket 套接字(模块):负责从传输层接收数据,并进行处理,并由底层交给操作系统。
    • 作用
      • 避免计算机学习各层的接口与协议的使用, socket 已经封装好了所有的接口,使用方便,提升开发效率。
      • socket 本质是一个模块。通过使用学习模块提供的功能,建立客户端与服务端的通信,使用方便.
  3. 单个客户与服务端通信

    • 服务端:

      import socket
      
      # 1. 创建socket对象
      phone = socket.socket() # 可以默认不写
      
      # 2. 绑定ip地址和端口(办卡)
      phone.bind(('127.0.0.1', 8888))  # 本地回环地址
      
      # 3. 监听.(开机状态)
      phone.listen(5)
      
      # 4. 接收连接
      print('start')
      conn, addr = phone.accept()  # 程序暂进入待机状态,等待用户端发送信息
      print(conn,addr)
      
      from_client_data = conn.recv(1024)  # 至多接收1024个字节
      print(f'来自客户端{addr}消息{from_client_data.decode("utf-8")}')
      to_client = input('>>>')
      conn.send(to_client.encode('utf-8'))
      
      conn.close()
      phone.close()
    • 客户端:

      import socket
      
      # 创建socket对象
      phone = socket.socket() # 可以默认不写
      
      # 连接服务器ip地址与端口
      phone.connect(('127.0.0.1', 8888))
      
      # 发消息
      to_server = input('>>>').strip()
      phone.send(to_server.encode('utf-8'))
      # 接收消息
      from_server_data = phone.recv(1024)  # 程序暂时进入待机状态,等待服务端的数据传过来
      
      print(f'来自服务端消息:{from_server_data.decode("utf-8")}')
      
      # 关机
      phone.close()
  4. 通信循环

    • 服务端:

      import socket
      
      phone = socket.socket()
      
      phone.bind(('127.0.0.1', 8888))
      
      phone.listen(5)
      
      # 接收连接
      
      while 1:
          print('start')
          conn, addr = phone.accept()  # 程序进入待机状态
          print(conn,addr)
          while 1:
              try:
                  from_client_data = conn.recv(1024)  # 至多接收1024个字节
                  if from_client_data == b'q':
                      break
                  print(f'来自客户端{addr}消息{from_client_data.decode("utf-8")}')
                  to_client = input('>>>')
                  conn.send(to_client.encode('utf-8'))
              except ConnectionResetError:
                  break
          conn.close()
      phone.close()
    • 客户端:

      import socket
      
      # 创建socket对象
      phone = socket.socket() 
      
      # 连接服务器ip地址与端口
      phone.connect(('127.0.0.1', 8888))
      
      # 发消息
      while 1:
          to_server = input('>>>').strip()
          if to_server.upper() == 'Q':
              phone.send('q'.encode('utf-8'))
              break
          phone.send(to_server.encode('utf-8'))
          # 接收消息
          from_server_data = phone.recv(1024)  # 待机,等待接收服务端的数据
          print(f'来自服务端消息:{from_server_data.decode("utf-8")}')
      
      # 关机
      phone.close()
  5. 通信,连接循环

    • 服务端:

      import socket
      
      phone = socket.socket() 
      
      # 2. 绑定ip地址和端口
      phone.bind(('127.0.0.1', 8888))  
      
      # 3. 监听.(开机状态)
      phone.listen(5)
      
      # 4. 接收连接
      print('start')
      conn, addr = phone.accept()  # 程序夯住
      while 1:
          try:
              from_client_data = conn.recv(1024)  # 至多接收1024个字节
              if from_client_data == b'q':
                  break
              print(f'来自客户端{addr}消息{from_client_data.decode("utf-8")}')
              to_client = input('>>>')
              conn.send(to_client.encode('utf-8'))
          except ConnectionResetError:
              break
      conn.close()
      phone.close()
    • 客户端:

      import socket
      
      # 1. 创建socket对象
      phone = socket.socket() 
      
      # 连接服务器ip地址与端口
      phone.connect(('127.0.0.1', 8888))
      
      # 发消息
      while 1:
          to_server = input('>>>').strip()
          if to_server.upper() == 'Q':
              phone.send('q'.encode('utf-8'))
              break
          phone.send(to_server.encode('utf-8'))
          # 接收消息
          from_server_data = phone.recv(1024)  # 夯住,等待服务端的数据传过来
          print(f'来自服务端消息:{from_server_data.decode("utf-8")}')
      
      # 关机
      phone.close()
  6. 利用socket完成获取远端命令

    • 服务端:

      import socket
      import subprocess
      
      phone = socket.socket()
      
      phone.bind(('127.0.0.1', 8888))
      
      phone.listen(5)
      
      # 4. 接收连接
      print('start')
      conn, addr = phone.accept()
      while 1:
          try:
              cmd = conn.recv(1024) #  dir
              obj = subprocess.Popen(cmd.decode('utf-8'),
                                     shell=True,
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.PIPE,
                                     )
      
              result = obj.stdout.read() + obj.stderr.read()
              conn.send(result)
          except ConnectionResetError:
              break
      conn.close()
      phone.close()
    • 用户端:

      import socket
      
      phone = socket.socket()
      
      phone.connect(('127.0.0.1', 8888))
      
      # 发消息
      while 1:
          cmd = input('>>>').strip()
          phone.send(cmd.encode('utf-8'))
          # 接收消息
          result = phone.recv(1024)  # 夯住,等待服务端的数据传过来
          print(result.decode('gbk'))
      
      # 关机
      phone.close()
    • 示例

      • 服务端:
      import socket
      import subprocess
      
      phone = socket.socket()
      
      phone.bind(('127.0.0.1',8888))
      
      phone.listen(5)
      
      print('start')
      conn,addr = phone.accept()
      while 1:
          try:
              cmd = conn.recv(1024)
              obj = subprocess.Popen(cmd.decode('utf-8'),
                                     shell=True,
                                     stdout = subprocess.PIPE,
                                     stderr = subprocess.PIPE,)
      
              result = obj.stdout.read() + obj.stderr.read()
              conn.send(result)
      
          except BrokenPipeError:
              break
      
      conn.close()
      phone.close()
    • 客户端:

      import socket
      
      phone = socket.socket()
      
      phone.connect(('127.0.0.1',8888))
      
      while 1 :
          cmd = input('>>>')
          phone.send(cmd.encode('utf-8'))
      
          result = phone.recv(1024)
          print(result.decode('utf-8'))
      
      phone.close()

以上是关于网络编程 I(socket)的主要内容,如果未能解决你的问题,请参考以下文章

Linux 网络编程三(socket代码详解)

网络编程 I(socket)

JAVA I/O网络Socket和ServerSocket

socket编程:I/O模型

网络I/O:Socket→RMI

深入Socket网络编程与I/O多路复用