网络、计算机网络的构成是什么?
网络: 在计算机领域中,网络是信息传输、接收、共享的虚拟平台,通过它可以把各个点、面(组织之间)、体(例如公共app)的信息联系到一起,从而实现这些资源的共享。 局域网: 多个设备(电脑手机等)都连接到了一个路由器上,就形成了一个局域网,路由器最终通过光纤或者双绞线连接到广域网,实现上网。 互联网: 无数个局域网、城域网等形成互联网
什么是网络编程?
网络编程就是对信息的发送和接收,通过操作相应的api调度计算机的硬件资源,并利用传输管道进行数据交流。
七层网络模型(来自百度)
基础层:物理层、数据链路层、网络层
传输层:TCP-UDP协议层、socket,网络编程是建立在传输层之上的
高级层:会话层、表示层、应用层

Socket
网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket,他是ip地址和端口的结合描述协议,也是tcp/ip协议相关api的总称。用于区分不同应用程序进程间的网络通信和连接。
Socket传输原理
通过IP地址和端口连接进行网络通讯
Socket与tcp
- tcp是面向连接的协议
- 通过三次握手建立连接,通讯完成是要拆除连接
- 由于tcp是面向连接的,所有只能用于端到端的通信,某一时刻只能连接到 某一个端口
Socket与udp(基于报文的传输)
- udp是面向无连接的
- udp数据包括目的端口号和源端口号的信息
- 面向无连接,可以进行广播发送, 并不局限于端到端。而tcp无法进行广播通讯
C/S模型
tcp/ip 协议中,两个进程间通信的主要模式为C/S模型(client-server)
目的: 协同网络中的计算机资源,服务模式、进程间的数据共享(例如网站中访问redis服务)
常见的C/S模型:FTP、SMTP、HTTP
报文
- 报文段是TCP/IP协议网络传输过程中,起着路由导航作用的。A进程发送到数据到B进程,A进程会将原始数据进行报文解析,然后加上对应的字节头,然后将字节头信息传递B进程,B进程将字节头解析以后得到报文段,再将报文段传递给应用层,应用层再经报文段解析成原始数据
- 报文段用于查询各个网络路由网段,ip地址、交换协议等ip数据包
- 报文在传输过程中会不断被封装成组、包、帧进行传输
传输协议
传输协议就是一种规定,一种约束.A和B进行通话,就需要A拨号、响铃、B接听,要遵循这些操作才能进行通话。
mac地址
mac 地址用于标注网络设备的位置,形如45-45-33-36-00-00 ,对比我们的居民身份证
UDP中的核心API
DatagramSocket
-
用于发送和接收udp消息的类,既是服务器,也是客户端
-
udp并没有合并包socket api中
-
DatagramSocket( ):创建简单实例,不指定端口和ip,会自动选择本地可用的端口进行发送
-
DatagramSocket(int port):创建监听固定端口的实例
-
DatagramSocket(int port,InetAddress localAddress)
-
receive(DatagramPacket d): 接收
-
send(DatagramPacket d): 发送
-
setSoTimeout(int timeout):设置超时时间,毫秒
-
close()
DatagramPacket
- 用于处理报文的类,封装报文和拆解报文,它是发送实体,也是接收实体
- DatagramPacket(byte[] buf,int offset,int length,InetAddress address, int port);前三个参数指定buff和buff的使用区间,后两个参数是目标机器的ip和端口,这两个参数仅仅在发送时有效,而DatagramPacket在作为接收实体时使用的是DatagramSocket的ip和端口。
- DatagramPacket(byte[] buf,int offset,int length,SocketAddress socketaddress),与2类似,SocketAddress相当于InetAddress+port
- setData(byte[] buf,int offset,int length),可以往DatagramPacket对象中set要发送的buf数组
- setAddress(InetAddress address):仅在发送时有效
- setPort(int port):仅在发送时有效
- ...
UDP单播
端对端之间的通信
UDP多播(组播)
给一组设备发送信息
UDP广播
给当前设备所在的网段的所有设备发送信息
UDP辅助TCP实现点对点传输
场景:在一个局域网中,在不知道服务器的ip和端口的情况下,仅仅知道服务器的公共UDP端口,从客户端发起一个UDP广播,服务器收到以后回送一个消息,客户端获取udp包,获取服务器的ip和端口号,然后使用tcp进行连接。
简单聊天室设计
UDP广播获取服务端端的ip和端口
- 服务端监听某个UDP端口,并向客户端回送本服务端的信息
- 以线程的方式启动,循环监听处理所有消息
- 启动客户端消息接收线程,使用CountDownLatch控制使得确定监听线程启动以后再启动广播线程,startDownLatch作为Listen的 构造参数,run()开始执行将计数器减1,表示接收线程已经开始正常启动,然后发送广播消息。使用CountDownLatch的await()方法阻塞 直到收到一个服务器的回送消息。调用监听线程类封装的方法获取ServerInfo.
服务端
- 使用线程的方式监听客户端的连接
- 每有一个客户端连接,服务器创建一个客户端处理线程,将处理客户端连接的Handler添加到本地队列中 打印客户端消息,采用回调的方式进行通知,将消息转发到所有连接的客户端
- 客户端消息的转发采用异步的方式,将任务丢进线程池中执行(任务为遍历遍历所有的客户端处理对象,依次发送消息)
- 监听本地输入流,将服务端输入的所有消息发送给所有的客户端
客户端
- 循环监听并读取从服务端发送来的消息
- 线程循环读取本地输入流,将本地输入的消息发送到服务端
聊天室服务器状态分析
服务器状态-繁忙
- 每个客户端都需要服务器进行双通等待(读取和写入两个线程),读取和写入分别是不同的线程
- 服务器为每条客户端创建两个线程,当有n个客户端时,服务器的实际线程数量是大于2n的(gc回收线程和创建服务器的主线程,监听客户端来源的线程,当有新客户端到达时,使用独立的线程去监听,连接客户端,转发部分使用的是单线程池)