预备知识

多线程

实现多线程

线程池

IO流

核心功能就是读和写
扩展功能对什么读写,怎么读写,如何优化读写

网络基础

IP

IP规定网络上所有的设备都必须有一个独一无二的IP地址,就好比是邮件上都必须注明收件人地址,邮递员才能将邮件送到。同理,每个IP信息包都必须包含有目的设备的IP地址,信息包才可以正确地送到目的地。同一设备不可以拥有多个IP地址,所有使用IP的网络设备至少有一个唯一的IP地址

OSI模型

TCP/IP模型

网络通信

基本思路:

  1. 存在着两台主机client,和server
  2. 两方通过ip和端口号确定对方位置
  3. 通过socket传递信息

TCP
TCP协议全称是传输控制协议是一种面向连接的、可靠的、基于字节流的传输层通信协议,由 IETF 的RFC 793定义。TCP 是面向连接的、可靠的流协议。,
• 它充分地实现了数据传输时各种控制功能,可以进行丢包时的重发控制,还可以对次序乱掉的分包进行顺序控制。而这些在 UDP 中都没有。
• 此外,TCP 作为一种面向有连接的协议,只有在确认通信对端存在时才会发送数据,从而可以控制通信流量的浪费。
• 根据 TCP 的这些机制,在 IP 这种无连接的网络上也能够实现高可靠性的通信( 主要通过检验和、序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现)客户端创建socket,服务端接受socket,然后再通过socket传递信息
• 用到的主要的类:
• Socket
• ServerSocket
• I/O相关
• 类之间的关系
• InetSocketAddress继承SocketAddress,作用是存储ip地址和端口号
• Inet4Address与Inet6Address继承InetAddress,作用存储p地址
创建

  1. private static class InetSocketAddressHolder {
  2. // The hostname of the Socket Address
  3. private String hostname;
  4. // The IP address of the Socket Address
  5. private InetAddress addr;
  6. // The port number of the Socket Address
  7. private int port;
  8. }
  9. //要端口和ip地址,InetAddress提供ip地址,port提供端口

分析

Socket构造方法做了些什么:

  1. 创建一个SocksSocketImpl实例
  2. 调用bind()绑定本地端口和地址(如果不为空)实际上是调用的SocksSocketImpl的bind方法
  3. 调用connect()连接远程主机和端口
    大多数会调用两个私有的构造函数,空实现以及传入Proxy构造对象时需要手动调用connect(),进行连接
    package-private一般是为了功能的实现
    ServerSocket构造方法做了些什么
  4. 创建一个SocksSocketImpl实例
  5. 调用bind()绑定本地监听端口(必须绑定)和地址以及确定backlog(无法绑定抛出异常)
  6. 参数port指定服务器要绑定的端口(即服务器要监听的端口,注意端口号为零时自动分配),参数backlog指定客户连接请求队列的长度,参数bindAddr指定服务器要绑定的IP地址。
  7. 默认构造方法:允许服务器在绑定到特定端口之前,先设置ServerSocket的一些选项。因为一旦服务器与特定端口绑定,有些选项就不能再改变了。
  1. public ServerSocket(int port, int backlog, InetAddress bindAddr)

设置Socket选项
·TCP_NODELAY:表示立即发送数据。
·SO_RESUSEADDR:表示是否允许重用Socket所绑定的本地地址。
·SO_TIMEOUT:表示接收数据时的等待超时时间。
·SO_LINGER:表示当执行Socket的close()方法时,是否立即关闭底层的Socket。
·SO_SNDBUF:表示发送数据的缓冲区的大小。
·SO_RCVBUF:表示接收数据的缓冲区的大小。
·SO_KEEPALIVE:表示对于长时间处于空闲状态的Socket,是否要自动把它关闭。
·OOBINLINE:表示是否支持发送1字节的TCP紧急数据。
设置ServerSocket选项
·SO_TIMEOUT:表示等待客户连接的超时时间。
·SO_REUSEADDR:表示是否允许重用服务器所绑定的地址。
·SO_RCVBUF:表示接收数据的缓冲区的大小
服务
• 客户端:对象创建成功并且连接到远程主机后可以获取一些信息,已经通过getOutPutStream()与getInputStream()获取I/o流对象读入和写入信息
• 服务器:监听接口接受客户端的socket对象,再从中获取信息
关闭
可以以一个标志作为是否结束的判断(比如输入bye)
半关闭:
调用Socket的close()方法关闭Socket后,它的输出流和输入流也都被关闭。有的时候,可能仅仅希望关闭输出流或输入流之一
shutdownInput():关闭输入流。shutdownOutput():关闭输出流。
完全关闭:
为了确保关闭,要将socket.close放在finally中(实现了java.lang.Auto Closable接口。这意味着如果在try代码块中打开或创建了这些类的实例,那么即使程序没有显式地关闭它们,Java虚拟机也会在退出try代码块时自动关闭它们,释放相关的资源)
服务器同时与多个客户端连接
方式1:为每个客户分配一个工作线程。
方式2:创建一个线程池,由其中的工作线程来为客户服务.
方式3:利用JDK的Java类库中现成的线程池,由它的工作线程来为客户服务。
单独分配线程

  1. 主线程负责接收客户端的连接,创造工作线程负责通信
  2. 每个线程负责一个客户端
    自定义线程池
    使用jdk内置线程池
    java.util.concurrent
    线程池的缺点
    1.死锁
    2.系统资源不足
    3.并发错误
    4.线程泄漏
    5.任务过载

UDP

• UDP 不提供复杂的控制机制,利用 IP 提供面向无连接的通信服务。
• 并且它是将应用程序发来的数据在收到的那一刻,立即按照原样发送到网络上的一种机制。即使是出现网络拥堵的情况,UDP 也无法进行流量控制等避免网络拥塞行为。
• 此外,传输途中出现丢包,UDP 也不负责重发。
• 甚至当包的到达顺序出现乱序时也没有纠正的功能。
• 如果需要以上的细节控制,不得不交由采用 UDP 的应用程序去处理。
• UDP 常用于一下几个方面:1.包总量较少的通信(DNS、SNMP等);2.视频、音频等多媒体通信(即时通信);3.限定于 LAN 等特定网络中的应用通信;4.广播通信(广播、多播)。
• 客户端通过DataPacket保存信息,DataSocket发送packet信息,服务端通过监听端口接受Packet

DataPacket

• 发送信息的packet必须要指定地址和端口,接受信息的packet则不必指定
• 数据报中只能存放字节形式的数据,在发送方,需要把其他格式的数据转换为字节序列,在接收方,需要把字节序列转换为原来格式的数据(可以利用ByteArrayOutputStream和DataOuputStream)
• 可以利用ByteArrayInputStream和DataInputStream来把字节序列转换为原来格式的数据

DataSocket

DatagramSocket类负责接收和发送数据报。在客户程序中,一般由操作系统为DatagramSocket类分配本地端口,这种端口也被称为匿名端口。在服务器程序中,一般由程序显式地为DatagramSocket类指定本地端口。

• 每个DatagramSocket对象都会与一个本地端口绑定(在构造方法中就自动绑定,不提供则随机分配),在此端口监听发送过来的数据报。在recieve()方法中还会进一步检查.
• connect()是可选的 ,但与TCP的连接不一样,前者不建立TCP意义上的连接,而是限制当前DatagramSocket或DatagramChannel只对参数指定的远程主机和UDP端口收发数据报。

组播

单播:提供点对点的通信。发送者每次发送的数据有着唯一的目的地址,只被一个接收者接收。前面介绍的TCP Socket和UDP Socket都只支持单播。
组播:发送者每次发送的数据可以被小组内的所有接收者接收。
广播:发送者每次发送的数据可以被传播范围内的所有接收者接收

原理

组播地址:
组播组内的所有主机共享同一个地址,这种地址被称为组播地址,组播地址是范围在224.0.0.0 ~239.255.255.255之间的IP地址。此范围内的所有地址的前4个二进制位都是“1110”。组播地址也被称为D类IP地址,
使用UDP:
大多数组播数据为音频或视频,这些数据一般都很大,即便部分数据在传输途中被丢失,接收方也仍然能识别信号。因此组播数据通过UDP发送,虽然不可靠,但比面向连接的TCP的传输速度快3倍以上。
TTL(Time to live)
这也是与单播UDP不同的地方

好处

如图:在从主机1到路由器2的途中数据只需要传输一次,(单播对数据进行了不必要的复制,浪费了许多网络带宽。如果采用组播,则可以大大提高传输效率,路由器会动态决定组播数据的路由,只在必要时才复制数据)。

实现

java.net.MulticastSocket具有组播的功能,它是DatagramSocket的子类

非阻塞通信

什么是阻塞

放弃CPU,暂停运行,只有等到导致阻塞的原因消除,才能恢复运行;或者被其他线程中断,该线程会退出阻塞状态,并且抛出InterruptedException(比如烧水,一直等水烧开后再做其他事)

阻塞的原因

线程阻塞

1.线程执行了Thread.sleep(int n)方法,线程放弃CPU,睡眠n ms,然后恢复运行。
2.线程要执行一段同步代码,由于无法获得相关的同步锁,只好进入阻塞状态,等到获得了同步锁,才能恢复运行。
3. 线程执行了一个对象的wait()方法,进入阻塞状态,只有等到其他线程执行了该对象的notify()或notifyAll() 方法,才可能将其唤醒。
4. 线程执行I/O操作或进行远程通信时,会因为等待相关的资源而进入阻塞状态。例如当线程执行System.in.read() 方法时,如果用户没有向控制台输入数据,则该线程会一直等读到了用户的输入数据才从read()方法返回。

客户端阻塞

  1. 请求与服务器建立连接时,即当线程执行Socket的带参数的构造方法,或执行Socket的connect()方法时,会进 入阻塞状态,直到连接成功,此线程才从Socket的构造方法或connect()方法返回。
  2. 线程从Socket的输入流读入数据时,如果没有足够的数据,就会进入阻塞状态,直到读到了足够的数据,或者到达 输入流的末尾,或者出现了异常,才从输入流的read()方法返回或异常中断.
  3. 输入流中有多少数据才算足够呢?这要看线程执行的read()方法的类。
    (1)int read():只要输入流中有1字节,就算足够。
    (2)int read(byte[] buff):只要输入流中的字节数目与参数buff数组的长度相同,就算足够。
    (3)String readLine():只要输入流中有1行字符串,就算足够。
  4. 线程向Socket的输出流写一批数据时,可能会进入阻塞状态,等到输出了所有的数据,或者出现异常,才从输出流 的write()方法返回或异常中断。
  5. 如果调用Socket的setSoLinger()方法设置了关闭Socket的延迟时间,那么当线程执行Socket的close()方法 时,会进入阻塞状态,直到底层Socket发送完所有剩余数据,或者超过了setSoLinger()方法设置的延迟时间,才从close()方法返回。

服务端阻塞

  1. 线程执行ServerSocket的accept()方法,等待客户的连接,直到接收到了客户连接,才从accept()方法返回。
  2. 线程从Socket的输入流读入数据时,如果输入流没有足够的数据,就会进入阻塞状态。
  3. 线程向Socket的输出流写一批数据时,可能会进入阻塞状态,等到输出了所有的数据,或者出现异常,才从输出流 的write()方法返回或异常中断。

实现

java.nio.channels包提供了支持非阻塞通信的类

·ServerSocketChannel:ServerSocket的替代类,支持阻塞通信与非阻塞通信。
·SocketChannel:Socket的替代类,支持阻塞通信与非阻塞通信。
·Selector:为ServerSocketChannel监控接收连接就绪事件,为 SocketChannel监控连接就绪、读就绪和写就绪事件。
·SelectionKey:代表ServerSocketChannel以及SocketChannel向Selector注册事件的句柄。当一个SelectionKey对象位于Selector对象的selected-keys集合中,就表示与这个SelectionKey对象相关的事件发生了。

java网络通信不止UDP,TCP的更多相关文章

  1. java 网络编程 UDP TCP

    网络编程 网络编程主要用于解决计算机与计算机(手机.平板..)之间的数据传输问题. 网络编程: 不需要基于html页面就可以达到数据之间的传输. 比如: feiQ , QQ , 微信....网页编程: ...

  2. Java基础之UDP协议和TCP协议简介及简单案例的实现

    写在前面的废话:马上要找工作了,做了一年的.net ,到要找工作了发现没几个大公司招聘.net工程师,真是坑爹呀.哎,java就java吧,咱从头开始学呗,啥也不说了,玩命撸吧,我真可怜啊. 摘要: ...

  3. Java网络编程之TCP、UDP

    Java网络编程之TCP.UDP 2014-11-25 15:23 513人阅读 评论(0) 收藏 举报 分类: java基础及多线程(28) 版权声明:本文为博主原创文章,未经博主允许不得转载.   ...

  4. java基础55 UDP通讯协议和TCP通讯协议

    本文知识点(目录): 1.概述    2.UDP通讯协议    3.TCPP通讯协议 1.概述 1.在java中网络通讯作为Socket(插座)通讯,要求两台都必须安装socket.    2.不同的 ...

  5. 4.Java网络编程之TCP/UDP

    常见传输协议: UDP , TCP UDP协议:    特点:         1.将数据及源和目的封装成数据包中,不需要建立连接         2.每个数据包的大小限制在64K内         ...

  6. Java网络通信初步认知

    本文转载自:http://wing011203.cnblogs.com/ 在这篇文章里,我们主要讨论如何使用Java实现网络通信,包括TCP通信.UDP通信.多播以及NIO. TCP连接 TCP的基础 ...

  7. Java程序员从笨鸟到菜鸟之(十三)java网络通信编程

    本文来自:曹胜欢博客专栏.转载请注明出处:http://blog.csdn.net/csh624366188 首先声明一下,刚开始学习java网络通信编程就对他有一种畏惧感,因为自己对网络一窍不通,所 ...

  8. JAVA 通过 Socket 实现 TCP 编程

    简介 TCP简介 TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议,由IETF的RFC 793定义.在简化的计算机 ...

  9. Java中的UDP协议编程

    一. UDP协议定义   UDP协议的全称是用户数据报,在网络中它与TCP协议一样用于处理数据包.在OSI模型中,在第四层——传输层,处于IP协议的上一层.UDP有不提供数据报分组.组装和不能对数据包 ...

随机推荐

  1. OpenStack Train版-12.创建虚拟网络并启动实例(控制节点)

    使用VMware虚拟机创建网络可能会有不可预测到的故障,可以通过dashboard界面,管理员创建admin用户的网络环境 1.第一种: 建立公共提供商网络在admin管理员用户下创建 source ...

  2. python sort() sorted()的区别

    sorted不保存 sort保存:

  3. SSH Keys vs GPG Keys

    SSH Keys vs GPG Keys SSH Keys SSH keys allow you to establish a secure connection between your compu ...

  4. 技术分享: CSS3 系列

    技术分享: CSS3 系列 css 一键换肤 css 打印样式,媒体查询 css 禁用选择 css 性能优化 css 计算单位 css 3D 特效 refs xgqfrms 2012-2020 www ...

  5. 微信小程序-云开发实战教程

    微信小程序-云开发实战教程 云函数,云存储,云数据库,云调用 https://developers.weixin.qq.com/miniprogram/dev/wxcloud/basis/gettin ...

  6. web effects collection

    web effects collection typewriter effect js 打字机效果 http://www.mattboldt.com/demos/typed-js/ https://g ...

  7. CSS Modules in depth

    CSS Modules in depth https://github.com/css-modules/css-modules https://webpack.js.org/loaders/css-l ...

  8. Koa 洋葱模型

    Koa 洋葱模型 let context = { data: [] }; async function middleware1(ctx, next) { console.log('action 001 ...

  9. SVG & Blob & Base64

    SVG & Blob https://developer.mozilla.org/en-US/docs/Web/API/Blob SVG & Base64 https://develo ...

  10. 初学c++,vc++6.0必备!

    文章首发 | 公众号:lunvey 作为一个纯粹的萌新,工作需要,刚接触到c++. 按照以往的经验,配置一个开发环境是首要的,其次便是边学边敲. c++入门书籍寻找了一堆,发现了一个共同点,在Wind ...