zoukankan      html  css  js  c++  java
  • 传输模型和套接字

    传输模型:

    1、传输模型

    基本模型:

    2、TCP协议

    OSI七层模型


    先有模型,再有协议

    TCP/IP四层模型:先有协议和应用,再有模型
    TCP:传输控制协议,先和目标建立连接,再传输数据 相当于打电话
    UDP:用户数据报协议,直接传输数据,目标地址在报文里面

    TCP建立连接:三次握手


    怎么连接的?为什么要三次?
    客户端:我要连接你
    服务端:好的,我准备好了
    客户端:我建立连接了
    三次保证同步,例如因为网络延迟导致两边收到消息延后,发出的报文就可能收不到或者不知道是谁的。

    数据传输

    断开连接:四次挥手

    客户端:我要关闭连接了
    服务端:好的,等一下
    服务端:我的数据都给你了,我要断开了
    客户端:好的,我断开了

    为什么多了一次:
    因为服务端可能还数据要发

    到底是一次连接传一次数据
    还是一次连接传多次数据
    都可以
    HTTP协议 前着 请求一次,响应一次
    Websocket 后者 服务端有新的消息就会发给建立连接的客户端

    3、IP地址和端口

    不同主机之间通信,先用ip确定某个主机,再用端口确定某一个应用程序。

    除了一些服务占用的端口外,其他端口由操作系统分配,总共65535端口
    127.0.0.1 自己的主机地址
    0.0.0.0 任意的主机地址

    套接字:

    1.创建套接字实例

    import socket
    sock = socket.socket()
    print(sock)
    
    <socket.socket fd=724, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0>


    fd:正整型数据,文件描述符(唯一标识了一个socket)

    domain:(域)
    AF_INET     ipv4

    AF_INET6    ipv6

    type:(套接字类型):
    SOCK_RAW     原始套接字    ——>使用原始套接字时候调用,原始套接字也就是链路层协议

    SOCK_STREAM   字节流套接字   ——>提供顺序,可靠,双向,基于连接的字节流。 可以支持带外数据传输机制。例如:TCP协议、FTP协议

    SOCK_DGRAM 数据报套接字   ——>支持数据报(无连接,不可靠的固定最大长度的消息)例如:UDP协议

    SOCK_SEQPACKET 有序分组套接字 ——>为固定最大长度的数据报提供有序,可靠,双向连接的数据传输路径; 消费者需要利用每个输入系统调用读取整个分组

    protocol(协议):

    IPPROTO_IP     IP传输协议

    IPPROTO_TCP    TCP传输协议

    IPPROTO_UDP   UDP协议

    IPPROTO_SCTP   SCTP传输协议

    IPPROTO_ICMP ICMP协议

    IPPROTO_IGMP   IGMP协议

    一般情况下IPPROTO_TCP、IPPROTO_UDP、IPPROTO_ICMP协议用的最多,UDP协议protocol就取IPPROTO_UDP,TCP协议protocol就取IPPROTO_TCP;一般情况下,我们让protocol等于0就可以,系统会给它默认的协议。但是要是使用raw socket协议,protocol就不能简单设为0,要与type参数匹配.

    三种套接字
    服务端套接字:
    1、监听套接字(相当于前台,把你分配给连接套接字之后,继续监听。如果一次连接过多,处理不过来的会挂起)
    2、连接套接字(相当于和你交流的人)
    客户端套接字

    2.建立连接

    服务端的端口不能由操作系统分配(一般是固定的,让客户端知道要请求哪个端口)
    服务端套接字的绑定和监听

    sock.bind(('',8888)) #服务端套接字绑定自己的IP地址与端口号,客户端那边可以不写,内核会给它分配一个临时的端口.不写就是绑定到本地,后面8888是端口
    sock
    <socket.socket fd=724, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('0.0.0.0', 9999)>
    sock.listen(5) #开始监听,5表示最大挂起数

    客户端套接字

    client = socket.socket()
    client.connect(('127.0.0.1',9999))
    client
    <socket.socket fd=872, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 58311), raddr=('127.0.0.1', 9999)>

    laddr表示本地地址,raddr表示远程连接的地址
    对于客户端来说 laddr是客户端ip + 操作系统分配的任意端口,raddr是服务端的ip+绑定的端口
    对于服务端来说 laddr是服务端的IP + 绑定的端口,raddr是客户端的IP+客户端系统分配的端口

    t = sock.accept() # 实例一个对等连接套接字,用来和客户端通信。如果没有客户端连接,会处于阻塞状态
    t
    (<socket.socket fd=676, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 58311)>,
    ('127.0.0.1', 58311))
    
    conn, addr = t # conn现在是连接套接字,addr是客户端地址和端口

    3.发送接受消息

    client.send(b'hello') # 客户端发送消息(字节类型,如果是字符串记得要encode),返回数据长度.客户端断开连接之后,会发送一个b''空字节
    conn.recv(1024) # 连接套接字接收消息,1024表示每次最大接收数据大小,可以通过循环把所有数据接受完,接收的消息是字节类型,记得decode。如果没有数据发过来,会处于阻塞状态

    4.断开连接

    client.close() #客户端程序运行完会自己断开
    conn.close() #服务端可以根据是否接到空,判断是否需要断开
  • 相关阅读:
    Linux设置高分辨率后无法进入X系统
    C++中struct和class的总结
    Jenkins 使用slave管理进行持续集成测试说明
    从BUG工具redmine上获取数据后借助python模块pycha 画出BUG分析类报表,利用xlsxwriter
    生成jmeter可用文件和必要参数化的csv
    从BUG工具redmine上获取数据后借助python模块pycha 画出BUG分析类报表
    遍历jenkins build后的文件夹,找出最新“build NO.”复制到制定目录进行操作
    计算http接口签名,并驱动其参数进行测试
    举一反三,取buglist中的url
    测试sq3数据库,读取数据库把内容输出到csv文件,附上输出到excel方法
  • 原文地址:https://www.cnblogs.com/woaixuexi9999/p/9291751.html
Copyright © 2011-2022 走看看