(1)咚咚客户端核心设计原理分析 - socket篇


Socket 套接字说明:
https://blog.csdn.net/carson_ho/article/details/53366856
计算机网络分为五层:物理层、数据链路层、网络层、运输层、应用层

端口号

0~1023:分配给系统的端口号 我们不能随便使用
1024~49151:登记端口号,主要是让第三方应用使用  但是必须在IANA(互联网数字分配机构)按照规定手续登记,
49152~65535:短暂端口号,是留给客户进程选择暂时使用,一个进程使用完就可以供其他进程使用。  Socket 就在这个区域用这个端口号。

C/S 通信结构
http://upload-images.jianshu.io/upload_images/944365-c57e88a0318ef517.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240
CoreModelSeller  里面做的事情

tcp协议
面向连接:长连接,不想http无状态断开模式
双向通信:建立通信后双方可以互相发送消息
可靠的:指的是通过TCP连接传送的数据,无差错,不丢失,不重复,并且按序到达。
面向字节流:流,指的是流入到进程或从进程流出的字符序列。简单来说,虽然有时候要传输的数据流太大,TCP报文长度有限制,不能一次传输完,要把它分为好几个数据块,但是由于可靠性保证,接收方可以按顺序接收数据块然后重新组成分块之前的数据流,所以TCP看起来就像直接互相传输字节流一样,面向字节流。
Tcp三次握手和三次挥手。

http://upload-images.jianshu.io/upload_images/944365-ca6e707d5bef40fd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240
为什么是三次握手:
第一步: SYN = 1  表示信号 表示请求连接 , seq = x  下次服务端返回的是 ack seq+1(x + 1)
第二步: SYN = 1 , ack = 1 ,(表示应答的同时表示请求) seq  = y ack = x + 1,表示收到客户端的消息,同事请求客户端建立连接
第三步: ack = 1,(表示回答了) seq = x + 1(表示请求下个数据的位置) ack = y+1(应答服务端的位置) 

为什么TCP建立连接需要三次握手?

答:防止服务器端因为接收了早已失效的连接请求报文从而一直等待客户端请求,从而浪费资源
客户端第一步发送消息的时候长期滞留,如果没有第三步,第二部就会建立连接,但是实际上是不需要的。


CP释放连接 
TCP释放连接需要四次挥手过程,现在假设A主动释放连接:(数据传输结束后,通信的双方都可释放连接)

第一次挥手:A发送释放信息到B;(发出去之后,A->B发送数据这条路径就断了)
第二次挥手:B收到A的释放信息之后,回复确认释放的信息:我同意你的释放连接请求  //这个时候b知道a已经发送完成数据了,但是我这边服务端b也还有数据没有发送全,需要再次进行将消息处理发送出去
第三次挥手:B发送“请求释放连接“信息给A,b这个时候消息发送完成后说:我这边消息已经发送完全了,可以关闭连段的连接了,

第四次挥手:A收到B发送的信息后向B发送确认释放信息:我同意你的释放连接请求,(c端断开消息,之后b端知道消息已经完成了,开始进行关闭消息的逻辑)

为什么TCP释放连接需要四次挥手?

为了保证双方都能通知对方“需要释放连接”,即在释放连接后都无法接收或发送消息给对方

需要明确的是:TCP是全双工模式,这意味着是双向都可以发送、接收的
释放连接的定义是:双方都无法接收或发送消息给对方,是双向的

UDP协议特点:无连接的、不可靠的、面向报文、没有拥塞控制
1.无连接的,能不能到达无所谓
2.不可靠的 因为UDP发出去的数据包发出去就不管了
3.面向报文,不惜那个是护具留的方式,
4.没有拥塞控制:拥塞,是指到达通信子网中某一部分的分组数量过多,使得该部分网络来不及处理,以致引起这部分乃至整个网络性能下降的现象,严重时甚至会导致网络通信业务陷入停顿,即出现死锁现象,就像交通堵塞一样。TCP建立连接后如果发送的数据因为信道质量的原因不能到达目的地,它会不断重发,有可能导致越来越塞,所以需要一个复杂的原理来控制拥塞。而UDP就没有这个烦恼,发出去就不管了。

应用场景,游戏,IP电话 实施视屏

socket 建立:  (本事就是一个api借口, 可以调用台阶自的多个方法) 
即套接字,是一个对 TCP / IP协议进行封装 的编程调用接口(API)

即通过Socket,我们才能在Andorid平台上通过 TCP/IP协议进行开发
Socket不是一种协议,而是一个编程调用接口(API),属于传输层(主要解决数据如何在网络中传输)
Socket ={(IP地址1:PORT端口号),(IP地址2:PORT端口号)}  c 端和 服务端

TCP是按照流的方式。

UDP是按照数据报套接字的方式。


Socket:采用 服务器主动发送数据的方式
即建立网络连接后,服务器可主动发送消息给客户端,而不需要由客户端向服务器发送请求可理解为:是服务器端有需要才进行通信

建立套接字:

// 步骤1:创建客户端 & 服务器的连接
// 创建Socket对象 & 指定服务端的IP及端口号 
Socket socket = new Socket("192.168.1.32", 1989);  
// 判断客户端和服务器是否连接成功  
    socket.isConnected());
// 步骤2:客户端 & 服务器 通信
// 通信包括:客户端 接收服务器的数据 & 发送数据 到 服务器


客户端实现套接字接口逻辑:
接收消息操作:
    <-- 操作1:接收服务器的数据 -->
            // 步骤1:创建输入流对象InputStream
            InputStream is = socket.getInputStream() 
            // 步骤2:创建输入流读取器对象 并传入输入流对象
            // 该对象作用:获取服务器返回的数据
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);

            // 步骤3:通过输入流读取器对象 接收服务器发送过来的数据
            br.readLine();
发送消息操作:
    <-- 操作2:发送数据 到 服务器 -->                  
            // 步骤1:从Socket 获得输出流对象OutputStream
            // 该对象作用:发送数据
            OutputStream outputStream = socket.getOutputStream(); 

            // 步骤2:写入需要发送的数据到输出流对象中
            outputStream.write(("Carson_Ho"+"\n").getBytes("utf-8"));
            // 特别注意:数据的结尾加上换行符才可让服务器端的readline()停止阻塞

            // 步骤3:发送数据到服务端 
            outputStream.flush();  


// 步骤3:断开客户端 & 服务器 连接

             os.close();
            // 断开 客户端发送到服务器 的连接,即关闭输出流对象OutputStream

            br.close();
            // 断开 服务器发送到客户端 的连接,即关闭输入流读取器对象BufferedReader

            socket.close();
            // 最终关闭整个Socket连接
服务端建立套接字接口逻辑不管:


长连接的心跳包逻辑

https://blog.csdn.net/lyj1005353553/article/details/71482387


心跳机制的由来:
http://www.52im.net/thread-281-1-1.html

通过tcp建立连接可以保持长连接,减少dns还厚建立连接的次数,
但是tcp长连接如果是不能检测到的话,其每次都发送数据,但是这个时候他其实已经断开了(路由器断网例子),这中效果比http就要差了,所以检测长连接有其必要性。
Tcp的keepalive 不能代替心跳机制的原因:
Tcp每次建立连接之后其实他一致处于established,及时中间断开都是,他还是一致处于这个状态,设置了keepalive 可以在默认7200s重新检查是否连接,否就会重新发送10次建立连接,但是本身连接失败,他就不管了,但是他是检测不到当前tcp连接的阻塞,但是心跳包,有很多功能,包括重新建立连接,
心跳保活机制的实现方案参考:
定时长期心跳包存在的问题,就是耗电和耗费流量,
在后台的拉长心跳时间,在前台的时候保持原先的样子,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值