博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PYTHON2.day02
阅读量:7233 次
发布时间:2019-06-29

本文共 9221 字,大约阅读时间需要 30 分钟。

前情回顾

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

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

  前:

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

    * 网络收发缓冲区
      
         【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
     * 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
总结 :tcp套接字和udp套接字编程区别

  1. 流式套接字是以字节流方式传输数据,数据报套接字以数据报形式传输

     2. tcp套接字会有粘包,udp套接字有消息边界不会粘包
     3. tcp套接字保证消息的完整性,udp套接字则不能
     4. tcp套接字依赖listen accept建立连接才能收发消息,udp套接字则不需要
     5. tcp套接字使用send,recv收发消息,udp套接字使用sendto,recvfrom

二. 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地址

    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

作业 :
    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

转载于:https://www.cnblogs.com/shengjia/p/10388304.html

你可能感兴趣的文章
.未来只有坚持自己的信念.
查看>>
TODO:Golang指针使用注意事项
查看>>
五大角色和主域控制器
查看>>
QTcpserver编程
查看>>
ScrollView + Listview 实现方案优选
查看>>
redis概述与使用
查看>>
linux下如何设置和查看系统环境变量
查看>>
jaxws-webservice编程
查看>>
网众安装U盘带WINPE和MaxDOS
查看>>
Linux man文档英语单词
查看>>
oracle的权限和角色区别
查看>>
组策略管理——软件限制策略(4)
查看>>
tcp的三次握手
查看>>
u盘中的ubuntu为了减少日志系统频繁写文件所修改的/etc/fstab
查看>>
RAID浅谈
查看>>
Map接口
查看>>
IntelliJ IDEA 使用教程
查看>>
『高级篇』docker之服务发现、部署更新和扩容(七)
查看>>
『高级篇』docker之了解CICD和DevOps(41)
查看>>
shell内置命令和外部命令区别
查看>>