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'\xc0\xa8\x01\x02') 将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
posted @ 2019-02-16 16:54  圣枷  阅读(249)  评论(0编辑  收藏  举报