从永远到永远-网络基础-Socket、TCP、Http

天下风云出我辈,一入江湖岁月催。皇图霸业谈笑间,不胜人间一场醉。
Socket、Tcp、Http这三个东西经常用,但一直不是很理解他们之间的关系。今天发哥在考我面试题时,问我“地址栏输入访问地址,会发生什么”。我就Java程序员角度做了解答(主要集中在MVC那部分了),他跟我说不严谨,顺便提到了“握手”。那一瞬间,我突然明白了这几个东西间的关系。
一、Socket、http、tcp概念
1.Socket是什么?
Socket是一个传输层(tcp、udp那层)的api封装。他基于操作系统实现(不同操作系统实现方式有不同)。开发者利用其进行网络编程,而不必在意底层细节,从而完成系统间的网络通讯。
在这里插入图片描述
2.Socket与tcp、http的关系是怎样的?

1>http协议:是应用层的一个协议,用来解决数据封装的。http请求有报文(包括请求报文和响应报文),http协议其实就是对这个报文格式的一个约束。(怎么发,收到了怎么解析等等)
2>ftp:类比http协议理解。
3>tcp、upd协议:解决数据在网络中传输的问题。

**我一直理解http是个数据请求,用于数据传输的,其实其数据的传输是利用传输层(tcp等)协议处理的。**更准确说,是基于socket连接的进行数据传输,tcp其实就是个协议。

在这里插入图片描述

在这里插入图片描述

二、网络编程发展
1、传统网络编程基本模型是client/server模型,server端绑定ip,监听端口。client端向服务端坚挺的地址发起请求,通过三次握手建立连接,连接成功双方开始通信。
请补充代码:
这种传统模式有一个弊端:当客户端是多个时,每次有一个请求,server端都要开启一个线程处理请求。在多线程的学习中,我们都知道线程资源是极其宝贵的,过多的请求回对服务器造成很大压力。
2、伪异步的方式处理(伪异步IO)
JDK1.5之前,采用任务队列+线程池这种伪异步的方式处理上述问题。具体就是将客户端的socket封装成一个task任务(一个实现runnable的类),之后投递到线程池中,配置相应队列实现

请补充代码:

3、关于异步、非阻塞IO。
声明三个概念:
1)IO:jdk1.4之前的传统IO,阻塞式IO。
2)NIO:jdk1.4提出的非阻塞New IO,此时还没有实现异步。
3)AIO:jdk1.7提出的异步IO,又叫NIO2.0,彻底实现了异步非阻塞。(为了区别以下统称AIO)

先说阻塞与非阻塞:
IO和NIO本质的区别:阻塞与非阻塞。
阻塞:应用程序获取网络数据时,如果传输速度很慢,程序就一直等着,知道传输完毕。

我们都知道tcp有三次握手。在牵手中,当服务端给客户端返回信息时,会先发送一个header,告诉客户端我准备给你发10m数据。然后再发一个body,里边是那10m数据。如果传输很慢,客户端就像个傻子一样,一直等着这10m数据传完。

同步和异步:

同步时,应用程序直接参与IO读写,程序阻塞在某个方法处,直到数据准备就绪,取数据。
异步时,应用程序不参与IO读写,底层读写由操作系统完成。操作系统读完成IO读写,将数据存至缓冲区(buffer)后,给应用程序发通知,应用程序直接从buffer中拿走数据。
在这里插入图片描述

注意:

NIO的代码实现起来挺复杂,buffer的使用和连接建立用着都挺膈应人。能应付面试就行,一般写的时候还是传统那一套。。。【手动狗头】
实现思路大体说一下:客户端的socket都包裹成一个channel,与服务器的连接也不是通过三次握手,而是每个客户端将自己的channel注册到服务端的选择器上,这个选择器通过轮询方式应对每个客户端的操作。
AIO的实现也挺膈应人,大体就是把channel选择器那部分又封装了一下,有一个递归方式去实现对各客户端的响应。有产品实现了这种方式,一般不会手写这部分代码了。

Netty是各基于NIO的框架,因为原生代码写得太复杂,netty简单易用(简单易用吗????【黑人问号脸】)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值