Socket网络编程笔记

881 阅读6分钟

网络、计算机网络的构成是什么?

网络: 在计算机领域中,网络是信息传输、接收、共享的虚拟平台,通过它可以把各个点、面(组织之间)、体(例如公共app)的信息联系到一起,从而实现这些资源的共享。 局域网: 多个设备(电脑手机等)都连接到了一个路由器上,就形成了一个局域网,路由器最终通过光纤或者双绞线连接到广域网,实现上网。 互联网: 无数个局域网、城域网等形成互联网

什么是网络编程?

网络编程就是对信息的发送和接收,通过操作相应的api调度计算机的硬件资源,并利用传输管道进行数据交流。

七层网络模型(来自百度)

基础层:物理层、数据链路层、网络层
传输层:TCP-UDP协议层、socket,网络编程是建立在传输层之上的 高级层:会话层、表示层、应用层

Socket

网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket,他是ip地址和端口的结合描述协议,也是tcp/ip协议相关api的总称。用于区分不同应用程序进程间的网络通信和连接。

Socket传输原理

通过IP地址和端口连接进行网络通讯

Socket与tcp

  1. tcp是面向连接的协议
  2. 通过三次握手建立连接,通讯完成是要拆除连接
  3. 由于tcp是面向连接的,所有只能用于端到端的通信,某一时刻只能连接到 某一个端口

Socket与udp(基于报文的传输)

  1. udp是面向无连接的
  2. udp数据包括目的端口号和源端口号的信息
  3. 面向无连接,可以进行广播发送, 并不局限于端到端。而tcp无法进行广播通讯

C/S模型

tcp/ip 协议中,两个进程间通信的主要模式为C/S模型(client-server) 目的: 协同网络中的计算机资源,服务模式、进程间的数据共享(例如网站中访问redis服务)
常见的C/S模型:FTP、SMTP、HTTP

报文

  1. 报文段是TCP/IP协议网络传输过程中,起着路由导航作用的。A进程发送到数据到B进程,A进程会将原始数据进行报文解析,然后加上对应的字节头,然后将字节头信息传递B进程,B进程将字节头解析以后得到报文段,再将报文段传递给应用层,应用层再经报文段解析成原始数据
  2. 报文段用于查询各个网络路由网段,ip地址、交换协议等ip数据包
  3. 报文在传输过程中会不断被封装成组、包、帧进行传输

传输协议

传输协议就是一种规定,一种约束.A和B进行通话,就需要A拨号、响铃、B接听,要遵循这些操作才能进行通话。

mac地址

mac 地址用于标注网络设备的位置,形如45-45-33-36-00-00 ,对比我们的居民身份证

UDP中的核心API

DatagramSocket

  1. 用于发送和接收udp消息的类,既是服务器,也是客户端

  2. udp并没有合并包socket api中

  3. DatagramSocket( ):创建简单实例,不指定端口和ip,会自动选择本地可用的端口进行发送

  4. DatagramSocket(int port):创建监听固定端口的实例

  5. DatagramSocket(int port,InetAddress localAddress)

  6. receive(DatagramPacket d): 接收

  7. send(DatagramPacket d): 发送

  8. setSoTimeout(int timeout):设置超时时间,毫秒

  9. close()

DatagramPacket

  1. 用于处理报文的类,封装报文和拆解报文,它是发送实体,也是接收实体
  2. DatagramPacket(byte[] buf,int offset,int length,InetAddress address, int port);前三个参数指定buff和buff的使用区间,后两个参数是目标机器的ip和端口,这两个参数仅仅在发送时有效,而DatagramPacket在作为接收实体时使用的是DatagramSocket的ip和端口。
  3. DatagramPacket(byte[] buf,int offset,int length,SocketAddress socketaddress),与2类似,SocketAddress相当于InetAddress+port
  4. setData(byte[] buf,int offset,int length),可以往DatagramPacket对象中set要发送的buf数组
  5. setAddress(InetAddress address):仅在发送时有效
  6. setPort(int port):仅在发送时有效
  7. ...

UDP单播

端对端之间的通信

UDP多播(组播)

给一组设备发送信息

UDP广播

给当前设备所在的网段的所有设备发送信息

UDP辅助TCP实现点对点传输

场景:在一个局域网中,在不知道服务器的ip和端口的情况下,仅仅知道服务器的公共UDP端口,从客户端发起一个UDP广播,服务器收到以后回送一个消息,客户端获取udp包,获取服务器的ip和端口号,然后使用tcp进行连接。

简单聊天室设计

UDP广播获取服务端端的ip和端口

  1. 服务端监听某个UDP端口,并向客户端回送本服务端的信息
  2. 以线程的方式启动,循环监听处理所有消息
  3. 启动客户端消息接收线程,使用CountDownLatch控制使得确定监听线程启动以后再启动广播线程,startDownLatch作为Listen的 构造参数,run()开始执行将计数器减1,表示接收线程已经开始正常启动,然后发送广播消息。使用CountDownLatch的await()方法阻塞 直到收到一个服务器的回送消息。调用监听线程类封装的方法获取ServerInfo.

服务端

  1. 使用线程的方式监听客户端的连接
  2. 每有一个客户端连接,服务器创建一个客户端处理线程,将处理客户端连接的Handler添加到本地队列中 打印客户端消息,采用回调的方式进行通知,将消息转发到所有连接的客户端
  3. 客户端消息的转发采用异步的方式,将任务丢进线程池中执行(任务为遍历遍历所有的客户端处理对象,依次发送消息)
  4. 监听本地输入流,将服务端输入的所有消息发送给所有的客户端

客户端

  1. 循环监听并读取从服务端发送来的消息
  2. 线程循环读取本地输入流,将本地输入的消息发送到服务端

聊天室服务器状态分析

服务器状态-繁忙

  1. 每个客户端都需要服务器进行双通等待(读取和写入两个线程),读取和写入分别是不同的线程
  2. 服务器为每条客户端创建两个线程,当有n个客户端时,服务器的实际线程数量是大于2n的(gc回收线程和创建服务器的主线程,监听客户端来源的线程,当有新客户端到达时,使用独立的线程去监听,连接客户端,转发部分使用的是单线程池)