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

    一、网络编程的目标

    编写一个C/S或B/S架构的基于网络通信的软件

    C/S架构:客户端---服务端
    B/S架构:浏览器----服务端

    学习socket编程就是要编写客户端软件和服务端软件,然后实现服务端和客户端基于网络通信

    服务端特点:1、不间断地提供服务;2、服务端要支持并发+高性能

    二、网络

    网络 = 物理连接介质 + 互联网协议

    互联网协议分为OSI七层,或TCP/IP五层:

    物理层:发送电信号-----基于二进制

    数据链路层:ethernet以太网协议-----基于mac地址,在局域网内通信

    网络层:IP协议-----基于IP地址

    传输层:TCP/UDP协议------基于端口(端口即应用程序与网卡关联的编号)

    应用层:HTTP、mail、ftp协议等

    IP协议的作用:一个是为每一台计算机分配IP地址,另一个是确定哪些地址在同一个子网络

    ARP协议:在同一个局域网内,根据IP地址获取mac地址,操作系统自动转换

    路由协议:网关与网关之间的通信

    TCP协议:TCP建立的是一个双向连接,也叫流式协议

                      3次握手,建立客户端和服务端的双向通路

                      4次挥手,断连接,服务端先发起断连

    mac地址 + IP地址 +端口就可以定位到世界上独一无二的应用软件;有了ARP协议,IP地址 + 端口就可以定位到世界上独一无二的应用软件

    三、socket编程

    sockct(套接字)是位于应用层和传输层之间的一个抽象层,专门把传输层以下的协议封装成接口给应用层使用。

    套接字有两种(或者称为有两个种族),分别是基于文件型的(AF_UNIX)和基于网络型的(AF_INET)。

    1、socket工作流程

    服务端:
    socket()---bind()---listen()---accept()---recv()---send()---close()

     服务端先初始化socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。

    服务端:

    socket()---connect()---send()---recv()---close()

    客户端初始化一个socket,然后连接服务器(connect),如果连接成功,这时客户端与服务端的连接就建立了。

    客户端发送数据请求(send),服务器端接收请求并处理请求(recv),然后把回应数据发送给客户端(send),客户端读取数据(recv),最后关闭连接(close),一次交互结束。

    bind()     绑定IP地址和端口。本地回环地址:127.0.0.1,端口:0到65535,其中0到1024是给系统用的。 服务端和客户端都需要有IP和端口,但只有服务端才绑定IP和端口
    listen()     括号里面的数字代表同一时间只能进来多少个请求
    accept()     等待信息
    reav(1024)     代表收消息,1024是一个最大的限制
    send()     回消息
    close()     关闭连接

    2、粘包

    只有TCP有粘包现象,UDP永远不会粘包,因为TCP协议是面向流的协议,而UDP是面向消息的协议。
    所谓粘包问题主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的

    两种情况下会发生粘包:
    1、发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数据量很小,会合到一起,产生粘包)
    2、接收方不及时接收缓冲区的包,造成多个包接收(客户端发送了一段数据,服务端只收了一小部分,服务端下次再收的时候还是从缓冲区拿上次遗留的数据,产生粘包)

    TCP是基于数据流的,于是收发的消息不能为空,这就需要在客户端和服务端都添加空消息的处理机制

    粘包的解决方法:
    为字节流加上自定义固定长度报头,报头中包含字节流长度,然后一次send到对端,对端在接收时,先从缓存中取出定长的报头,然后再取真实数据

    使用struct模块解决粘包

    struct模块的作用:
    1、把整型数字转成bytes类型
    2、转成的bytes是固定长度

    可以把报头做成字典,字典里包含将要发送的真实数据的详细信息,然后json序列化,然后用struck将序列化后的数据长度打包成4个字节(4个字节足够用了)

    发送时:
    先发报头长度
    再编码报头内容然后发送
    最后发真实内容

    接收时:
    先收报头长度,用struct取出来
    根据取出的长度收取报头内容,然后解码,反序列化
    从反序列化的结果中取出待取数据的详细信息,然后去取真实的数据内容

    3、基于UDP协议通信的套接字
    UDP是基于数据报的,一发对应一收
    特点:无连接
    优点:发送效率高,但有效传输的数据量最多为512bytes
    缺点:不可靠,发送数据无须对方确认,容易丢包(而TCP是发一条数据必须收到对方的确认后才会从自己的操作系统缓存清除该条消息,否则重发)

  • 相关阅读:
    flutter 刷新和初始化
    flutter 复杂数据模型 转换
    flutter 刷新组件
    flutter wrap 流式布局
    添加横纵布局 和 页面保活
    跳转首页结构并且加载launch插件
    迟到的AFO
    [ELSE]自闭选手的自我修养
    [题解]UOJ#41 矩阵变换
    [题解]HDU 3555 Bomb
  • 原文地址:https://www.cnblogs.com/Python1/p/8981914.html
Copyright © 2011-2022 走看看