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

    1.网络通信协议
    网络通讯的基本要素
    C/S构架
    OSI七层模型
    2.socket编程


    server(服务器) client(客户端)

    网络通讯的基本要素
    1.物理连接介质 2.通讯协议


    应用 表示 会话 传输 网络 数据链路 物理

    以太网协议


    1.物理层 规定 物理介质的相关规范 比如网线接口是什么样的 有几根线
    二进制
    问题:无法理解单纯的二进制数据
    2.数据链路层 工作在这一层的是以太网协议
    规定一组电信号有多少位 规定每组电信号包含什么样的内容
    每一台电脑必须拥有一个全球唯一的mac地址(可以有多个)
    通过广播的方式 来找到对方的mac地址
    255-1 一个局域网的容量
    问题:不可能全球广播 会造成广播风暴(广播太多 网络瘫痪)

    3.网络层
    工作在这一层的是ip协议
    网络地址协议:给每一个计算机分配一个ip地址
    dns(域名解析服务器) 将域名转为ip地址
    ARP协议是根据ip获取对方的mac地址
    在IP协议中 包含一个路由协议: 用最短的路径找到对方的主机
    路由器就相当于古代的驿站

    通常是ipv4
    0.0.0.0-255.255.255.255
    前三段称之为网络号 后一段称之为主机号
    子网掩码用来判断是否处于同一个局域网
    arp协议 把ip转成mac地址的协议

    ip协议最主要的目的就是找到全球范围内的某一个局域网 与某一台具体的计算机

    问题:一个数据包到达对方计算机后 到底交给哪一个应用程序来处理

    端口范围0-65535 0-1023为系统占用端口

    传输层: 用于规范数据传输方式(tcp udp) 以及识别应用程序(端口号)


    四次挥手 断开连接 也是为了确保数据传输完整性

    TCP
    优点 可靠 保证数据传输是完整的
    缺点 由于每次都需要传输确认信息 导致传输效率降低
    适用于 对数据完整性要求高的程序 比如支付数据 文字信息等
    相当于手机

    udp 不可靠传输
    优点 由于不需要传输确认信息 所以传输效率高于tcp协议
    缺点 传输数据可能不完整 完全不关心对方是否收到数据 把数据发送到网络中
    适用于:视频 语音 即时对战游戏
    相当于对讲机

    网络传输数据 其实就是一层层封包与一层层解包的过程

    应用层:主要是用于规定 双防应用程序之间以什么形式来传输数据
    这一层的数据形式是由程序员自己来定制的 长剑有HTTP FTP Email等等


    重点关注的就是传输层协议 以及网络地址

    socket
    封装了传输层一堆协议的模块
    当你需要开发一款C/S结构的应用程序的时候 就需要使用它
    基于C/S结构的应用程序 需要分别开发服务器和客户端程序
    学习的重点就是如何使用socket编写服务器程序 以及客户端程序

        通常应该先开发服务器

    服务器程序的大致流程
    1.创建socket对象
    2.绑定ip和port
    3.监听连接
    4.接受请求
    5.收发数据
    6.断开连接
    
    import socket
    
    #默认情况下创建的是基于网络的TCP协议的socket对象
    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    #参数1:协议家族 网络的为AF_INET
    #参数2:type  用于设置采用的传输协议 TCP的为SOCK_STREAM UDP为SOCK_DGRAM
    
    #重用端口号 当你已经关闭了服务器 但是还是报异常说 端口占用时  可以使用
    s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    
    s.bind(('127.0.0.1',8888))
    #端口号取值:0-65535 0-1023是系统保留的
    
    s.listen()#监听客户端的连接
    
    #c:当接受到请求时  会返回一个表示客户端的socket对象
    #客户端的socket对象就负责这个客户端的数据手法
    #c_addr  同时返回对方的ip和端口 打包成元组
    c,addr=s.accept()#接受客户端的连接请求
    
    #开始接受数据
    #recv接受数据
    #buffersize 缓冲区大小  单位为字节 1kb
    data=c.recv(1024)
    print(data.decode('utf-8'))
    c.close()#断开与客户端的连接
    s.close()#关闭服务器socket 后续的客户端就无法在连接服务器了  一般正常服务器是不会关闭的
    import socket
    
    #创建socket对象
    c=socket.socket()
    
    #与服务器建立连接 传入服务器的ip和端口
    c.connect(('127.0.0.1',8888))
    
    
    #收发数据 只能发送bytes类型的数据(任何数据都能发)
    c.send('你真帅'.encode('utf-8'))
    
    
    #断开与服务器的连接
    c.close()
    import socket
    s=socket.socket()
    s.bind(('127.0.0.1',8888))
    s.listen()
    
    
    
    # 连接循环  重复接受客户端连接请求 直到关闭程序为止
    while True:
        c,addr=s.accept()
        print('收到了一个请求')
        # 通讯循环 重复的收发数据 直到断开连接
        while True:
            try:
                data=c.recv(1024)# 也是一个阻塞函数 会一直等到对方发送数据为止
                # 如果对方断开了连接  会重复收到空消息
                if not data:
                    print('客户端下线了')
                    break
                print('收到了一个数据',data)
                # 给客户端 返回一个消息
                data+=b'dsb'
                c.send(data)
            except ConnectionResetError:
                print('对方异常断开连接')
                break
    
                # s.send(data) #错误示范 服务器只负责 接收请求 建立连接 具体的收发数据由客户端socket来做
                # 注意:服务器和客户端之间 不能同时都执行recv  由于recv是一个阻塞 会导致双方卡死
    
                # windows中 客户端 强行下线 服务器会抛出ConnectionResetError异常   来try处理
                # windows中 客户端 正常下线 会重复收到空消息
    
                # linux 客户端 强行下线 服务器会重复收到空消息
                # linux 客户端 正常下线 服务器也会重复收到空消息
                # 结论:既要处理异常 又要加上空消息的判断 保证服务器不会被终止或死循环
      
    改进版服务器
    import socket
    c=socket.socket()
    c.connect(('127.0.0.1',8888))
    
    
    
    while True:
        msg=input('>>>:(q.退出)')
        if msg=='q':
            break
        elif not msg:
            continue
        # 发送数据
        c.send(msg.encode('utf-8'))
        # 接收服务器返回的数据
        data=c.recv(1024)
        print(data)
    改进版客户端
  • 相关阅读:
    freebsd安装mysql
    freebsd安装ports
    分布式拒绝服务攻击
    如何用命令获知当前是一年中的第多少周和今天是周几
    freebsd软件包下载地址
    mod_wsgi的两种模式
    freebsd中/etc/rc.conf配置文件导致不能启动的问题
    进程ID[PID(Process ID)]与端口号[(Port ID)]的联系
    Java EE之HttpServletRequest
    Chrome之控制台使用【转载】
  • 原文地址:https://www.cnblogs.com/gengbinjia/p/10452285.html
Copyright © 2011-2022 走看看