• PYTHON2.day02


    前情回顾

    1. OSI七层模型  tcp/ip模型
    2. 三次握手和四次挥手
    3. tcp和udp的区别
    4. 网络概念 : 网络主机  端口   IP地址   域名
    5. 套接字编程 : 网络编程技术手段
            流式套接字 : TCP
                  数据报套接字:UDP

    6. TCP套接字流程
        服务端:socket() --> bind() --> listen() --> accept() --> recv(),send() --> close()

         客户端:socket() --> connect() --> send(),recv() --> close()

    *********************************************************

    循环

      1 import socket
      2 
      3 #创建套接字
      4 sockfd = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
      5 #绑定地址
      6 sockfd.bind(('0.0.0.0',8888))
      7 
      8 #设置监听
      9 sockfd.listen(5)
     10 #等待处理客户连接
     11 print("waitting for connect...")
     12 connfd,addr = sockfd.accept()
     13 print("Connect from",addr)#客户地址
     14 
     15 #收发消息
     16 while  True:
     17     #收
     18     data = connfd.recv(1024)
     19     if not data:
     20         break
     21     print("Receive message",data.decode())
     22     #发
     23     n= connfd.send(b"Receve your message!!")
     24     print("Send %d bytes"%n)
     25 #关闭套接字
     26 connfd.close()#连接套接字
     27 sockfd.close()#监听套接字
    tcp_server.py
      1 from socket import *
      2 
      3 #创套接字
      4 sockfd = socket()
      5 
      6 #发起连接
      7 server_addr = ('192.168.43.165',8888)
      8 sockfd.connect(server_addr)
      9 
     10 #收发消息
     11 while  True:
     12     #发
     13     data = input(">>")
     14     sockfd.send(data.encode())
     15     if not data:
     16         break
     17     #收
     18     data = sockfd.recv(1024)
     19     print("From server:",data.decode())
     20 
     21 #关闭套接子
     22 sockfd.close()
    tcp_client.py

    循环

    一. tcp 套接字数据传输特点

      * tcp连接中当一端退出,另一端如果阻塞在recv,此时recv会立即返回一个空字串。

        * tcp连接中如果一端已经不存在,让然试图通过send发送则会产生BrokenPipeError

        * 一个监听套接字可以同时连接多个客户端,也能够重复被连接

      前:

    3_try前

      1 import socket
      2 
      3 #创建套接字
      4 sockfd = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
      5 #绑定地址
      6 sockfd.bind(('0.0.0.0',8888))
      7 
      8 #设置监听
      9 sockfd.listen(5)
     10 #等待处理客户连接
     11 while  True:
     12     print("waitting for connect...")
     13     try:
     14         connfd,addr = sockfd.accept()
     15     except KeyboardInterrupt:
     16         print("Server exit")
     17         break
     18     print("Connect from",addr)#客户地址
     19     #收发消息
     20     while  True:
     21         #收
     22         data = connfd.recv(1024)
     23         if not data:
     24             break
     25         print("Receive message",data.decode())
     26         #发
     27         n= connfd.send(b"Receve your message!!")
     28         print("Send %d bytes"%n)
     29     #关闭套接字
     30     connfd.close()#连接套接字
     31 sockfd.close()#监听套接字
    tcp_server.py

      1 from socket import *
      2 
      3 #创套接字
      4 sockfd = socket()
      5 
      6 #发起连接
      7 server_addr = ('172.40.71.149',8888)
      8 sockfd.connect(server_addr)
      9 
     10 #收发消息
     11 while  True:
     12     #发
     13     data = input(">>")
     14     sockfd.send(data.encode())
     15     if not data:
     16         break
     17     #收
     18     data = sockfd.recv(1024)
     19     print("From server:",data.decode())
     20 
     21 #关闭套接子
     22 sockfd.close()
     23 
    tcp_clent.py

    3.2try后_ctrl_c
        * 网络收发缓冲区
          
             【1】网络缓冲区有效的协调了消息的收发速度
             【2】send和recv实际是向缓冲区发送接收消息,当缓冲区不为空recv就不会阻塞。
        

      1 import socket
      2 
      3 #创建套接字
      4 sockfd = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
      5 #绑定地址
      6 sockfd.bind(('0.0.0.0',8888))
      7 
      8 #设置监听
      9 sockfd.listen(5)
     10 #等待处理客户连接
     11 while  True:
     12     print("waitting for connect...")
     13     try:
     14         connfd,addr = sockfd.accept()
     15     except KeyboardInterrupt:
     16         print("Server exit")
     17         break
     18     print("Connect from",addr)#客户地址
     19     #收发消息
     20     while  True:
     21         #收
     22         data = connfd.recv(5)
     23         if not data:
     24             break
     25         print("Receive message",data.decode())
     26         #发
     27         n= connfd.send(b"Receve your message!!")
     28         print("Send %d bytes"%n)
     29     #关闭套接字
     30     connfd.close()#连接套接字
     31 sockfd.close()#监听套接字
    tcp_server.py
      1 from socket import *
      2 
      3 #创套接字
      4 sockfd = socket()
      5 
      6 #发起连接
      7 server_addr = ('172.40.71.149',8888)
      8 sockfd.connect(server_addr)
      9 
     10 #收发消息
     11 while  True:
     12     #发
     13     data = input(">>")
     14     sockfd.send(data.encode())
     15     if not data:
     16         break
     17     #收
     18     data = sockfd.recv(1024)
     19     print("From server:",data.decode())
     20 
     21 #关闭套接子
     22 sockfd.close()
     23 
    tcp_clent.py
    ddp_5_缓冲器
    ddp_5_缓冲器     * tcp粘包
          
             【1】 原因:tcp以字节流方式传输,没有消息边界。多次发送的消息被一次接收,此时就会形成粘包。

            【2】 影响:如果每次发送内容是一个独立的含义,需要接收端独立解析此时粘包会有影响。

            【3】 处理:1. 人为的添加消息边界
                              2. 控制发送速度


    二. UDP套接字编程

      1. 服务端流程
          
             【1】 创建数据报套接字
                 sockfd = socket(AF_INET,SOCK_DGRAM)
            
             【2】 绑定地址
                 sockfd.bind(addr)
            
             【3】 消息收发
                
                     data,addr = sockfd.recvfrom(buffersize)

                     功能: 接收UDP消息
                     参数: 每次最多接收多少字节
                     返回值: data  接收到的内容
                              addr  消息发送方地址
                    
                     n = sockfd.sendto(data,addr)
                     功能: 发送UDP消息
                     参数: data  发送的内容 bytes格式
                            addr  目标地址
                     返回值:发送的字节数
              
             【4】关闭套接字
                 sockfd.close()

      2. 客户端流程
          
                 【1】 创建套接字
                 【2】 收发消息
                 【3】 关闭套接字

      1 from socket import *
      2 
      3 #创建数据报套接字
      4 sockfd = socket(AF_INET,SOCK_DGRAM)
      5 #绑定地址
      6 server_addr=('0.0.0.0',8888)
      7 sockfd.bind(server_addr)
      8 
      9 #消息收发
     10 while True:
     11     try:
     12         data,addr = sockfd.recvfrom(5)
     13     except KeyboardInterrupt:
     14         print("Server exit")
     15         break
     16     print("Receive from %s:%s"%(addr,data.decode()))#addr地址,返回元组
     17     sockfd.sendto(b"Thank for you msg",addr)
     18 
     19 #关闭套接字
     20 sockfd.close()
    udp_serve.py
      1 from socket import *
      2 
      3 #定义服务器地址
      4 HOST = '172.40.71.149'
      5 POST = 8888
      6 ADDR = (HOST,POST)
      7 
      8 #创建udp套接字
      9 sockfd = socket(AF_INET,SOCK_DGRAM)
     10 
     11 #收发消息
     12 while True:
     13     data = input("Msg>>")
     14     if not data:
     15         break
     16     sockfd.sendto(data.encode(),ADDR)
     17     msg,addr = sockfd.recvfrom(1024)
     18     print("Receive from server:",msg.decode())
     19 
     20 sockfd.close()
     21 
    udp_clent.py
    ddp_5_缓冲器
    总结 :tcp套接字和udp套接字编程区别

      1. 流式套接字是以字节流方式传输数据,数据报套接字以数据报形式传输
         2. tcp套接字会有粘包,udp套接字有消息边界不会粘包
         3. tcp套接字保证消息的完整性,udp套接字则不能
         4. tcp套接字依赖listen accept建立连接才能收发消息,udp套接字则不需要
         5. tcp套接字使用send,recv收发消息,udp套接字使用sendto,recvfrom

    udp_new1多终端
    二. socket模块方法和socket套接字属性

      1. 部分socket模块方法
          
             【1】 gethostname()  获取计算机名
             【2】 gethostbyname('www.baidu.com')  获取主机ip地址
             【3】 getservbyname('mysql') 获取服务端口号
             【4】 getservbyport(3306)  获取端口对应服务
             【5】 inet_aton('192.168.1.2') 将IP转换为bytes子串
             【6】 inet_ntoa(b'xc0xa8x01x02') 将bytes子串转换为IP地址

    gethostnamegethostbynamegetservbyname

    getservbyportinet_atoninet_aton

        2. 套接字属性

            【1】 sockfd.type  套接字类型

            【2】 sockfd.family 套接字地址类型

            【3】 sockfd.getsockname() 获取套接字绑定地址

            【4】 sockfd.fileno() 获取套接字的文件描述符
                
                     文件描述符:系统中每一个IO操作都会分配一个整数作为编号,该整数即这个IO操作的文件描述符。

                    特点: 文件描述符是系统用来区分处理IO的标志,不会重复。

        【5】 sockfd.getpeername() 获取连接套接字客户端地址

        【6】 sockfd.setsockopt(level,option,value)
                   功能:设置套接字选项
                         参数: level  选项类别   SOL_SOCKET
                                option 具体选项内容
                                      value  选项值
            
             【7】 sockfd.getsockopt(level,option)
                   功能 : 获取套接字选项值

      1 from socket import *
      2 
      3 #创建套接字对象
      4 s = socket()
      5 
      6 s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)#对套接字设置为可以立即重用端口(绑定前)
      7 print(s.getsockopt(SOL_SOCKET,SO_REUSEADDR))
      8 
      9 print(s.family)#地址类型
     10 print(s.type)#套接字类型
     11 
     12 
     13 s.bind(('172.40.71.149',8888))#先绑定
     14 print(s.getsockname())#获取绑定的addr
     15 
     16 print(s.fileno())#获取文件描述符
     17 
     18 #print(s.getpeername())
     19 #OSError: [Errno 107] Transport endpoint is not connected
     20 s.listen(3)
     21 c,addr = s.accept()
     22 print(c.getpeername())#获取对应的客户地址,相当于addr
     23 
    sock_attr.py
    设置套接字选项
    三. UDP套接字广播

        广播定义 : 一端发送多点接收
        
             广播地址 : 每个网络的最大地址为发送广播的地址,向该地址发送,则网段内所有主机都能接收。

      1 from socket import *
      2  #创建数据报套接字
      3 s = socket(AF_INET,SOCK_DGRAM)
      4  #设置可以发送接受广播
      5 s.setsockopt(SOL_SOCKET,SO_BROADCAST,1)
      6  #选择一个接受地址
      7 s.bind(('0.0.0.0',6475))
      8 
      9 while True:
     10     try:
     11         msg,addr = s.recvfrom(1024)
     12         print("从%s接受广播:%s"%(addr,msg.decode()))
     13     except  KeyboardInterrupt:
     14         break
     15     except Exception as e:
     16         print(e)
     17 s.close()
     18 
    broad_recv.py
      1 from socket import *
      2 from time import sleep
      3 
      4 #目标地址
      5 dest =('172.40.71.255',6475)
      6 s = socket(AF_INET,SOCK_DGRAM)
      7 s.setsockopt(SOL_SOCKET,SO_BROADCAST,1)
      8 
      9 
     10 data = '''******
     11 12           ******'''
     13 
     14 while True:
     15     sleep(2)
     16     s.sendto(data.encode(),dest)
     17 
     18 s.close()
     19 
    broad_send.py


    四. TCP套接字之HTTP传输

      1. HTTP协议 (超文本传输协议)

          【1】 用途 : 网页获取,数据的传输

            【2】 特点 : * 应用层协议,传输层使用tcp传输
                                         * 简单,灵活,很多语言都有HTTP专门接口
                                         * 无状态,协议不记录传输内容
                                         * http1.1 支持持久连接,丰富了请求类型

        【3】 网页请求过程

                1.客户端(浏览器)通过tcp传输,发送http请求给服务端
                     2.服务端接收到http请求后进行解析
                     3.服务端处理请求内容,组织响应内容
                     4.服务端将响应内容以http响应格式发送给浏览器
                     5.浏览器接收到响应内容,解析展示
        
             【4】 HTTP请求

                * 请求行 : 具体的请求类别和请求内容
              
                            GET         /        HTTP/1.1

               请求类别   请求内容     协议版本

                        请求类别:每个请求类别表示要做不同的事情
                            
                             GET : 获取网络资源
                             POST :提交一定的信息,得到反馈
                             HEAD : 只获取网络资源的响应头
                             PUT : 更新服务器资源
                             DELETE : 删除服务器资源
                             CONNECT
                             TRACE : 测试
                             OPTIONS : 获取服务器性能信息


                     * 请求头:对请求的进一步解释和描述

                     Accept-Encoding: gzip
     
                     * 空行


                     * 请求体: 请求参数或者提交内容


      1 from socket import *
      2 
      3 #创建套接字
      4 s = socket()
      5 s.bind(('0.0.0.0',8000))
      6 s.listen(3)
      7 
      8 c,addr = s.accept()#接收浏览器连接
      9 print("Connect from",addr)
     10 data = c.recv(4096)#浏览器发送请求
     11 print(data)
     12 #组织http相应
     13 date = '''Http/1.1 200 ok
     14 Content-Type:text/html
     15 
     16 hello world
     17 '''
     18 c.send(data.encode())#符合http响应格式
     19 
     20 c.close()
     21 s.close()
    httptest.py

    http请求

    作业 :
        1. 使用tcp完成一个文件的传输,将文件从客户端发送给服务端。要求文件可以是文本,也可以是图片
         2. 记住http请求格式和请求行每部分含义。了解

    请求类型
         3. 能够自己写出tcp udp的基础代码

      1 from socket import *
      2 
      3 s = socket()
      4 s.bind(('172.40.71.149',8888))
      5 s.listen(3)
      6 
      7 c,addr = s.accept()
      8 print("Connect from",addr)
      9 
     10 
     11 f= open('mo.jpg','wb')
     12 
     13 while True:
     14     data = c.recv(1024)
     15     if not data:
     16         break
     17     f.write(data)
     18 
     19 f.close()
     20 c.close()
     21 s.close()
    recvfile.py
      1 from socket import *
      2 
      3 s = socket()
      4 s.connect(('172.40.71.149',8888))
      5 
      6 f =open('one_list_app.jpg','rb')
      7 
      8 while True:
      9     data = f.read(1024)
     10     if not data:
     11         break
     12     s.send(data)
     13 
     14 f.close()
     15 s.close()
    send_file.py
    homework
  • 相关阅读:
    《网络是怎样连接的》读书笔记一
    移植mplayer到开发板
    解决ubuntu安装ssh服务无法打开解析包问题
    嵌入式软件工程师面经
    c语言-数组、指针面试题
    Linux命令- echo、grep 、重定向、1>&2、2>&1的介绍
    回调函数的作用
    数据结构-单链表回环函数判断
    算法-一步步教你如何用c语言实现堆排序(非递归)
    算法-快速排序
  • 原文地址:https://www.cnblogs.com/shengjia/p/10388304.html
Copyright © 2020-2023  润新知