gwuj 发表于 2018-8-14 09:48:45

python学习之网络编程

一、socket模块  
    socket模块提供了底层的接口,通过socket模块可以实现不同计算机的通信
  
    ip+port定位了计算机中应用程序的具体位置,socket绑定ip+port来建立链接,socket的方法详情:
  
    socket(family, type, proto): socket函数创建一个socket对象,使用socket对象创建连接,
  
    family协议族,默认AF_INET,ipv4协议,type,socket类型,proto协议类型
  

  
    bind((ip, port)): 绑定服务器地址
  
    listen(n): 监听socket创建的链接, n代表指定连接队列数,
  
    connect(('127.0.0.1', 8080)): 连接到服务端
  
    accept():等待客户端连接,返回连接对象和客户端ip组成的元组
  
    recv(n): 接收数据,n代表接受固定的数据
  
    send(data): 发送数据
  

  
    例子:模拟客户端服务端通信
  
    server:
  
    #!/usr/bin/python
  
    # --*-- coding: utf-8 --*--
  

  
    import socket
  
    phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  
    phone.bind(('127.0.0.1', 8080))
  

  
    phone.listen(5)
  

  
    print('starting...')
  

  
    conn, addr = phone.accept()
  
    print(conn)
  
    print('client addr: ', addr)
  
    print('ready to read msg')
  
    client_msg = conn.recv(1024)
  
    print('client msg: %s' %(client_msg))
  
    conn.send(client_msg.upper())
  
    conn.close()
  
    phone.close()
  

  
    client
  
    #!/usr/bin/pytthon
  
    # --*-- coding: utf-8 --*--
  
    import socket
  
    phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  
    phone.connect(('127.0.0.1', 8080))
  

  
    phone.send('hello'.encode('utf-8'))
  

  
    back_msg = phone.recv(1024)
  
    print(back_msg.decode('gbk'))
  
    phone.close()
  

  
    模拟循环发送接收数据
  
    server
  
    import socket
  
    phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  
    phone.bind(('127.0.0.1', 8080))
  
    phone.listen(5)
  

  
    while True:
  
      print('starting...')
  
      conn, addr = phone.accept()
  
      print('client addr ', addr)
  
      while True:
  
            try:
  
                client_msg = conn.recv(1024)
  
                if not client_msg: break
  
                print('client_msg: %s' %client_msg)
  
                conn.send(client_msg.upper())
  
            except Exception:
  
                break
  
      conn.close()
  
    phone.close()
  

  
    client
  
    import socket
  
    phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  
    phone.connect(('127.0.0.1', 8080))
  

  
    while True:
  
      msg = input(">>: ")
  
      if not msg: continue
  
      phone.send(msg.encode('utf-8'))
  
      back_msg = phone.recv(1024)
  
      print(back_msg.decode('utf-8'))
  
    phone.close()
  

  
    模拟远程执行命令,并返回结果
  
    server
  
    import socket
  
    import subprocess
  
    phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  
    phone.bind(('127.0.0.1', 8080))
  
    phone.listen(5)
  

  
    while True:
  
      print('starting...')
  
      conn,addr = phone.accept()
  
      print('client addr: ', addr)
  
      while True:
  
            try:
  
                cmd = conn.recv(1024)
  
                if not cmd: break
  
                res = subprocess.Popen(cmd.decode('utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  
                err = res.stderr.read()
  
                if err:
  
                  cmd_res = err
  
                else:
  
                  cmd_res = res.stdout.read()
  
                conn.send(cmd_res)
  
            except Exception:
  
                break
  
      conn.close()
  
    phone.close()
  

  
    client
  
    import socket
  
    phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  
    phone.connect(('127.0.0.1', 8080))
  

  
    while True:
  
      cmd = input('>>: ').strip()
  
      if not cmd: continue
  
      phone.send(cmd.encode('utf-8'))
  
      back_msg = phone.recv(1024)
  
      print(back_msg.decode('gbk'))
  
    phone.close()
  

  
    粘包现象,数据包无规则断开,出现不希望的断开现象
  
    server
  
    from socket import *
  
    import time
  
    tcp_server = socket(AF_INET, SOCK_STREAM)
  
    tcp_server.bind(('127.0.0.1', 8080))
  
    tcp_server.listen(5)
  

  
    conn, addr = tcp_server.accept()
  
    res1 = conn.recv(5)
  
    res2 = conn.recv(5)
  
    res3 = conn.recv(7)
  
    print(res1.decode('gbk'))
  
    print(res2.decode('gbk'))
  
    print(res3.decode('gbk'))
  

  
    client
  
    from socket import *
  
    import time
  

  
    tcp_client = socket(AF_INET, SOCK_STREAM)
  
    tcp_client.connect(('127.0.0.1', 8080))
  

  
    tcp_client.send('hello world'.encode('utf-8'))
  
    time.sleep(5)
  
    tcp_client.send('egon666'.encode('utf-8'))
  

  
    解决粘包问题,使用struct模块,打包数据并解包数据
  
    例子:
  
    server
  
      import socket
  
      import subprocess
  
      import struct
  
      import json
  

  
      phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  
      phone.bind(('127.0.0.1', 8080))
  
      phone.listen(5)
  

  
      while True:
  
            print('starting...')
  
            conn, addr = phone.accept()
  
            print('client addr: ', addr)
  
            while True:
  
                try:
  
                  cmd = conn.recv(1024)
  
                  if not cmd:break
  
                  res = subprocess.Popen(cmd.decode('utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  
                  err = res.stderr.read()
  
                  if err:
  
                        cmd_res = err
  
                  else:
  
                        cmd_res = res.stdout.read()
  

  
                  head_dict = {'filename': None, 'hash': None, 'total_size': len(cmd_res)}
  
                  head_json = json.dumps(head_dict)
  

  
                  head_bytes = head_json.encode('utf-8')
  
                  print(struct.pack('i', len(head_bytes)))
  
                  conn.send(struct.pack('i', len(head_bytes)))
  
                  conn.send(head_bytes)
  
                  conn.send(cmd_res)
  

  
                except Exception:
  
                  break
  
            conn.close()
  
      phone.close()
  

  
      client
  
      import socket
  
      import struct
  
      import json
  

  
      phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  
      phone.connect(('127.0.0.1', 8080))
  

  
      while True:
  
            cmd = input('>>: ').strip()
  
            if not cmd: continue
  
            phone.send(cmd.encode('utf-8'))
  
            head_struct = phone.recv(4)
  
            #print(head_struct)
  
            head_len = struct.unpack('i', head_struct)
  
            head_bytes = phone.recv(head_len)
  
            head_json = head_bytes.decode('utf-8')
  
            #print(head_json)
  
            head_dict = json.loads(head_json)
  
            #print(head_dict)
  
            total_size = head_dict['total_size']
  
            recv_size = 0
  
            data = b''
  
            while recv_size < total_size:
  
                recv_data = phone.recv(1024)
  
                data += recv_data
  
                recv_size += len(recv_data)
  
            print(data.decode('gbk'))
  
      phone.close()
页: [1]
查看完整版本: python学习之网络编程