zoukankan      html  css  js  c++  java
  • 网络编程

    网络编程 
    什么socket?

    TCP(Transmission Control Protocol)可靠的、面向连接的协议(eg:打电话)、传输效率低全双工通信(发送缓存&接收缓存)、面向字节流。
    使用TCP的应用:Web浏览器;电子邮件、文件传输程序。

    UDP(User Datagram Protocol)不可靠的、无连接的服务,传输效率高(发送前时延小),一对一、一对多、多对一、多对多、面向报文,尽最大
    努力服务,无拥塞控制。使用UDP的应用:域名系统 (DNS);视频流;IP语音(VoIP)。
       
    软件
    客户端:CS架构, client -> server
    浏览器:BS架构, browser -> server

    为什么要网络通信发送的是字节?而不是字符串?
    py3, send/recv 都是字节
    py2, send/recv 都是字符串


    服务端:
    accept,阻塞:等待客户端来连接。
    recv, 阻塞:等待客户端发来数据。

    客户端:
    connect,阻塞:一直在连接,直到连接成功才往下运行其他代码。
    recv, 阻塞:等待服务端发来数据。

    服务端:
     1 import socket
     2 
     3 server = socket.socket()
     4 
     5 server.bind(('127.0.0.1',8001))
     6 
     7 server.listen(5)
     8 
     9 while True:
    10     conn,addr = server.accept()
    11     # 字节类型
    12     try:
    13         while True:
    14             data = conn.recv(1024) # 阻塞
    15             if data == b'exit':
    16                 break
    17             response = data + b' SB'
    18             conn.send(response)
    19     except ConnectionResetError:#防止客户端终端后 服务端异常  window环境下使用
    20         break
    21 
    22     conn.close()

    客户端:

     1 import socket
     2 
     3 sk = socket.socket()
     4 
     5 sk.connect(('127.0.0.1',8001))
     6 
     7 while True:
     8     name = input("请输入姓名:")
     9     sk.send(name.encode('utf-8')) # 字节
    10 
    11     if name == 'exit':
    12         break
    13 
    14     response = sk.recv(1024) # 字节
    15     print(response.decode('utf-8'))
    16 
    17 sk.close()

    socket粘包

    socket的粘包为在数据量小与时间间隔短的情况下 优化算法使数据减少IO以达到提高效率,减少网络IO的一种方式

    socket下的send与recv并不是一对一的  可以一对多 多对一即可  

    粘包主要是接收端不知所接收的大小(即不知数据的开头与结尾)  只要明确数据的大小 即可解决粘包导致的缺点 

    一般可以使用struck来达到效果

    send  : 只需要copy data     send不是直接操作网卡的   本质上是数据由用户程序copy到操作系统缓存    操作系统来调用网卡传输     

    recv: 1. wait data   2. copy data  时间较长   

    struct用法

     1 import struct
     2 res=struct.pack("i","")
     3 print(res)
     4 print(len(res))
     5 obj=struct.unpack("i",res)
     6 print(obj[0])import struct
     7 res=struct.pack("i","")
     8 print(res)
     9 print(len(res))
    10 obj=struct.unpack("i",res)
    11 print(obj[0])
    struct

    subprocess用法

    import subprocess
    
    res=subprocess.Popen("dir",
                         shell=True,
                         stderr=subprocess.PIPE,
                         stdout=subprocess.PIPE)
    print(res.stdout.read().decode("gbk"))
    subprocess

    SSH Server

     1 import socket
     2 import subprocess
     3 
     4 server = socket.socket()
     5 
     6 server.bind(('127.0.0.1',8008))
     7 
     8 server.listen(5)
     9 
    10 while True:
    11     print("server is working.....")
    12     conn,addr = server.accept()
    13     # 字节类型
    14     while True:
    15         # 针对window系统
    16 
    17         try:
    18             cmd = conn.recv(1024).decode("utf8") # 阻塞
    19             if cmd.encode("utf-8") == b'exit':
    20                 break
    21             res=subprocess.Popen(cmd,
    22                              shell=True,
    23                              stderr=subprocess.PIPE,
    24                              stdout=subprocess.PIPE,
    25                              )
    26             # print("stdout",res.stdout.read())
    27             # print("stderr",res.stderr.read().decode("gbk"))
    28             out=res.stdout.read()
    29             err=res.stderr.read()
    30 
    31             print("out响应长度",len(out))
    32             print("err响应长度",len(err))
    33             if err:
    34                  import struct
    35                  header_pack = struct.pack("i", len(err))
    36                  conn.send(header_pack)
    37                  conn.send(err)
    38             else:
    39                  #构建报头
    40                  import struct
    41                  header_pack=struct.pack("i",len(out))
    42                  print("header_pack",header_pack)
    43                  # # 发送报头
    44                  conn.send(header_pack)
    45                  # 发送数据
    46                  conn.send(out)
    47 
    48         except Exception as e:
    49             break
    50 
    51 
    52     conn.close()
    View Code

    SSH Client

     1 import socket
     2 import struct
     3 sk = socket.socket()
     4 
     5 sk.connect(('127.0.0.1',8008))
     6 
     7 while 1:
     8     cmd = input("请输入命令:")
     9     sk.send(cmd.encode('utf-8')) # 字节
    10     if cmd=="":
    11         continue
    12     if cmd == 'exit':
    13         break
    14 
    15     header_pack=sk.recv(4)
    16     data_length=struct.unpack("i",header_pack)[0]
    17     print("data_length",data_length)
    18     '''
    19     b'xxx/xxx/xxx/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'
    20 
    21 
    22     '''
    23 
    24     recv_data_length=0
    25     recv_data=b""
    26 
    27     while recv_data_length<data_length:
    28         data=sk.recv(1024)
    29         recv_data_length+=len(data)
    30         recv_data+=data
    31 
    32     print(recv_data.decode("gbk"))
    33 
    34 
    35 sk.close()
    View Code

    socketserver可以实现并发的网络通信

    server

     1 import socketserver
     2 
     3 class Myserver(socketserver.BaseRequestHandler):
     4     def handle(self):# handel之内的逻辑由程序员编写,request等同于socket对象conn
     5         # 字节类型
     6         while 1:
     7             # 针对window系统
     8             try:
     9                 print("等待信息")
    10                 data = self.request.recv(1024)  # 阻塞
    11                 # 针对linux
    12                 if len(data) == 0:
    13                     break
    14                 if data == b'exit':
    15                     break
    16                 response = data + b'SB'
    17                 self.request.send(response)
    18             except Exception as e:
    19                 break
    20 
    21         self.request.close()
    22 
    23 
    24 # 1 创建socket对象 2 self.socket.bind()  3 self.socket.listen(5)
    25 # server=socketserver.ForkingUDPServer(("127.0.0.1",8899),Myserver)
    26 server=socketserver.ThreadingTCPServer(("127.0.0.1",8899),Myserver) # socket建立,bind,listen方法
    27 
    28 server.serve_forever()#类似于accept方法

     client

     1 import socket
     2 
     3 sk = socket.socket()
     4 
     5 sk.connect(('127.0.0.1',8899))
     6 
     7 while 1:
     8     name = input(">>>>:")
     9     sk.send(name.encode('utf-8')) # 字节
    10 
    11     response = sk.recv(1024) # 字节
    12     print(response.decode('utf-8'))
  • 相关阅读:
    ural(Timus) 1019 Line Painting
    ACMICPC Live Archive 2031 Dance Dance Revolution
    poj 3321 Apple Tree
    其他OJ 树型DP 选课
    poj 3548 Restoring the digits
    ACMICPC Live Archive 3031 Cable TV Network
    递归循环获取指定节点下面的所有子节点
    手动触发asp.net页面验证控件事件
    子级Repeater获取父级Repeater绑定项的值
    没有列名的数据绑定
  • 原文地址:https://www.cnblogs.com/kxuan/p/14083912.html
Copyright © 2011-2022 走看看