zoukankan      html  css  js  c++  java
  • 假期(网络编程)

    """
    一、客户端/服务端架构:
        1、硬件C/S架构(打印机)
        2、软件C/S架构
            互联网中处处都是CS架构,服务端与客户端
        CS架构与socket的关系
            - 我们学习socket就是为了完成C/S架构的开发
    
    二、OSI七层模型:
        一个完整的计算机系统是由硬件、操作系统、应用软件三者组成,一台计算机只能自己玩自己,要想跟别人玩就需要上网了
        互联网的核心就是由一堆协议组成,协议就是标准,比如全世界人通信的标准是英语;
        如果把计算机比做人,那么互联网协议就是计算机界的英语了,如果所有的计算机都学会了这门英语,那么就可以互相通信了
        为何学习socket一定要先学习互联网协议:
            - 1、首先我们的目标是基于socket编程,来开发一款自己的cs架构软件
            - 2、其次cs架构软件(软件属于应用层)是基于网络进行通信的
            - 3、网络的核心即一堆协议,协议即标准,你想开发一款基于网络通信的软件,就必须遵循这些标准
    
    三、socket层
        socket层位于运输层和应用层之间,即socket抽象层
    
    四、socket是什么?
        socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,socket其实就是一个门面模式,它吧复杂的
        TCP/IP协议族隐藏在了socket接口的后面,对用户来说,一组简单的接口就是全部,让socket去组织数据,以符合指定的协议
        所以我们无需深入理解tcp/udp协议,socket已经帮我们封装好了,我们只需要遵循socket的规定去编程,写出的程序自然符合标准
        - 也有人将socket说成是IP+port,IP是用来标识互联网中的一台主机的位置,而port是用来标识这台主机上的一个应用程序,IP地址
          配置到网卡上的,而port是应用程序开启的,IP与port的绑定就标识了互联网中独一无二的应用程序
          程序的pid是同一台机器上不同进程或者线程的标识
    
    五、套接字的分类:
        - 基于文件类型的套接字家族
            套接字家族的名字:AF_UNIX
            unix一切皆文件,基于文件的套接字调用的就是底层文件系统来取数据,两个套接字进程运行在同一机器,可以通过访问同一个
            间接完成通信。
        - 基于网络类型的套接字家族
            套接字家族的名字:AF_INET
            ···所有的地址家族中,AF_INET是使用最广泛的一个,python支持很多种地址家族,但是由于我们只关心网络编程,所以我们
            大部分时间都只是使用AF_INET
    
    六、套接字的工作流程:
        一个生活中的场景:你要给你前对象打电话,先拨号,前对象听到电话铃声后拿起电话,这时候你俩就建立起来了不正当的链接,然后
        就可以进行不正当的交易了。交易完成后,挂断电话结束此次交谈;
        先从服务端说起,服务端先初始化socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端链接
        在这个时候如果有客户端初始化一个socket,然后链接服务器(connect),如果链接成功,这时客户端与服务端的链接就建立了。
        客户端发送数据请求,服务端接收请求并处理,然后把回应数据发送给客户端,客户端读取数据,关闭链接,交互结束
        - socket函数的用法
            import socket
            socket.socket(socket_family,socket_type,protocal=0)
            socket_family:可以是AF_UNIX或者是AF_INET;socket_type可以是SOCK_STREAM或SOCK_DGRAM,protocol一般默认为0
    
            获取tcp/ip 套接字
            tcpsock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    
            获取udp/ip 套接字
            udpsock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    
            由于socket模块中有太多的属性,我们直接在这里使用 from xxx import * 的语句导入,这样就可以减少代码量
            eg:tcpsock = socket(AF_INET,SOCK_STREAM)
        - 服务端套接字函数
            s.bind()绑定(主机,端口号)到套接字
            s.listen()开始tcp监听
            s.accept()被动接受tcp客户的连接,(阻塞式)等待连接的到来
        - 客户端套接字函数
            c.connect()被动初始化tcp服务器连接
            c.connect_ex() connect()函数的扩展版本,出错时返回错误码,而不是抛出异常
        - 公共用途的套接字函数
            s.recv()接受tcp数据
            s.send()发送tcp数据(send在待发送数据量大于已缓存区剩余的空间时,数据丢失,不会发完)
            s.sendall()发送完整的tcp数据(本质就是循环send,···数据不会丢失)
            s.recvfrom()接受udp数据
            s.sendto()发送udp数据
            s.getpeername()链接到当前套接字的远程地址
            s.getsockname()当前套接字的地址
            s.getsockopt()返回指定套接字的参数
            s.setsockopt()设置指定套接字的参数
            s.close()关闭套接字链接
        - 面向锁的套接字方法
            s.setblocking()设置套接字的阻塞与非阻塞模式
            s.settimeout()设置阻塞套接字操作的超时时间
            s.gettimeout()得到阻塞套接字操作的超时时间
        - 面向文件的套接字函数
            s.fileno()套接字的文件描述符
            s.makefile()创建一个与该套接字相关的文件
    七、基于tcp的套接字
        tcp是基于链接的,必须先启动服务端,然后再启动客户端去链接服务端
        - tcp服务端:
            server = socket()   #创建服务器套接字
            server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
            server.bind()       #把地址绑定到套接字
            server.listen()     #监听链接
            while true:         #服务器无限循环
                client,addr = server.accept()    #接受客户端链接
                while True:                 #通信循环
                    client.recv()/client.send()   #接收与发送数据
                client.close()  #关闭客户端套接字
            server.close()       #关闭服务器套接字
        - tcp客户端:
            client = socket()    #创建客户端套接字
            client.connect()     #尝试链接服务器
            while True:
                client.send()/client.recv()   #发送/接收数据
            client.close()      #关闭客户端套接字
    
    八、基于udp的套接字
        - udp服务端
            server = socket()     #创建服务器套接字
            server.bind()         #绑定套接字地址
            while True:           #服务器无线循环
                client,addr = server.recvfrom()/server.sendto()    #接收与发送数据
            server.close()     #关闭服务器套接字
        - udp客户端
            client = socket()      #创建客户端套接字
            while True:            #通信循环
                client.sendto()/client.recvfrom()    #发送与接收数据
            client.close()  #关闭客户端套接字
    
    九、粘包现象(了解)
        如果当我们用socket模拟cmd执行远程命令时,有些数据太长,超过了1024个字节,一次接受不完,就会造成粘包
        - 什么是粘包?
            只有tcp才有粘包现象,udp永远不会粘包,因为udp是基于流收发数据的
            所谓粘包的问题主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少数据造成的
        - 粘包的解决
            - struct模块
            - 自定义报头
            - ···
        - 什么时候才会发生粘包?
            发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数据很小会喝到一起,产生粘包)
            接收方不及时接收缓冲区的包,造成多个包接收产生粘包
        - 了解
            tcp是可靠传输,udp是不可靠传输
    
    十、socketserver模块
        - 终极必杀技
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    """
  • 相关阅读:
    HTML基础 整理
    今天课堂总结
    课后习题
    JAVA的文件创建
    JAVA_输入输出流 异常处理
    12.23流水账号
    12.22 repeater 删除
    12.22 repeater 修改
    12.22 repeater 添加
    12.22 repeater 主页
  • 原文地址:https://www.cnblogs.com/52-qq/p/8449470.html
Copyright © 2011-2022 走看看