socket

1.

1.什么是socket套接字

image-20200716124339165

socket是应用层与传输层的一个抽象,将复杂的TCP/IP协议隐藏在Socket接口之后,只对应用层暴露简单的接口

2.

ServerSocket 类的作用是创建 Socket (套接字)的服务端, 而 Socket 类的作用是创建 Socket 的客户端。 在.

ServerSocket 类中的 public Socket accept()方法的作用是侦昕并接收此套接字的连接。 此方法在连接传入之前一直阻塞。 public Socket accept()方法的返回值是 Socket 类型 。

InputStream 类中的 read()方法 也同样具有阻塞特性 。

read()方法阻塞的原因是客户端并未发送数据到服务端,服务端一直在尝试读取从客户 端传递过来的数据,因为客户端从未发送数据给服务端,所以服务端一直在阻塞。

new ServerSocket (8088);”中的 8088 是设置的服务器的 Socket 端口 号

构造方法 public Socket (String host, int port)的第 一个参数 host 可以写成 IP 地址或域 名 。

1.客户端向服务端传递字符串

//服务端读
char [] charArray = new char [3] ;
...
InputStream inputStream = socket getinputStream();
InputStre缸nReader inputStreamReader = new InputStreamReader (inputStream) ;
int readLength = inputStreamReader . read(charArray) ;
while(readLength != -1){
.....
}
//客户端通过outputStream写
OutputStream outputStream = socket . getOutputStream() ; 
outputStream . write ( ” 我是外星人 ” . getBytes()) ; 
outputStream.close() ;

2.允许多次调用 write()方法进行写入操作

write() 方法允许多次被调用 ,每执行一次就代表传递一次数据。(前提流没有关闭)

读的那一端while循环去读,直到写的那一端调用close,代表到达流的结尾,不再传输数据

  1. 实现服务端与客户端多次的往来通信

前面的 实验都是服务端与客户端只进行了 l 次 通信, 那么如何实现连续多次的长连接通信呢?

就是流不关,多写几次读写的代码,。

4.调用 Stream 的 close()方法造成 Socket 关闭

inputStream . close();

此行代码的功能是将 InputStream 关闭 。 Stream 在 Socket 技术中进行应用时, 如果关闭 返回的 Stream ,将关闭关联的 Socket (套接字)

如果 Socket 关闭,则服务端与客户端不能进行通信。 因 此 , 当执行代码 OutputStream outputStream = socket.getOutputStream()取得输出流时,就会 出现异常。

5.使用 Socket 传递 PNG 图片文件(字节流)

读到缓存的字节数组中。

3 次“握手气的过程如下 。

1 )客户端到服务端 : 我要连接。

2 )服务端到客户端:好的, 已经连接上了 。

3 )客户端到服务端:收到, 确认已连接上了 。

4)4 次挥手过程 。见其他地方

6.“握手”的时机与立即传数据的特性

服务端与客户端进行“握手”的时机不是在执行 accpet()方法时 ,而是在 ServerSocket 对象创建出来并且绑定到指定的地址与端口时。

  1. 结合多线程 Thread 实现通信

在 Socket 技术中,常用的实践方式就是 Socket 结合 Thread 多线程技术,客户端每发起 一次新的请求,就把这个请求交给新创建的线程来执行这次业务。当然,如果使用线程池技 术,则会更加高效。

ServerSocketServerSocket server Socket =new ServerSocket(8888) ; 
int runTag = 1 ;
while (run Tag == 1) { 

Socket socket= serverSocket. a ccept() ; 
BeginThread beginThread = new BeginThread(socket); 
beginThread.start();
}
serverSocket . close();

2.ServerSocket类的使用

1.超时:

setSoTimeout (timeout) 方法 的作用是设置超时时 间 ,通过指定超 时 timeout 值启用/禁 用 SO TIMEOUT ,以 ms 为单位。

如 果超过超时值, 将 引 发 java.net. SocketTimeoutException , 但 Se凹erSocket 仍旧有效, 在结合 try-catch 结构后 , 还可 以 继续进 行 accept()方法 的操作。 SO_TIMEOUT 选项必须在进入阻塞操作前被启用才能生效。

timeout 0 被解释为无穷大超时值,默认值是 0 , 即永远等待

getSoTimeout() 方法的作用是获取 SO TIMEOUT 的设置

2.构造方法 public ServerSocket( int port,int backlog)

利用指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号 port。 对 port 端 口参数传递值为 0 ,意味着将自动分配空闲 的端口号。

传入 backlog 参数的作用是设置(允许接受客户端连 接请求的个数,默认是50)最大等待队列长度,如果队列己满,则拒绝该连接(抛出异常 Connection refused :connect)。

3.构造方法 ServerSocket (int port, int backlog, lnetAddress bindAddr)的使用

使用指定的 port 和 backlog 将 Socket 绑定到本地 InetAddress bindAddr 来创建服务端.

如果 bindAddr 为 null ,则默认接受任 何 / 所有本地地址上的连接 。 注意, 端口号必须 0 ~ 65535 (包括两者) 。

注:多宿主主机代表一台计算机有两块网卡, 每个网卡有不同的 IP 地址, 也有可能出现一 台计算机有 l 块网卡, 但这块网卡有多个 IP 地址的情况。

区别:

ServerSocket 类有 3 个构造方法, 在使用上还是有一些区别的 。

I )使用构造方法 public ServerSocket (int port)和 public ServerSocket (int p。此, int backlog)

创建 ServerSocket 对象, 则客户端可以使用服务器任意的 IP 连接到 ServerSocket 对象中 。

2 )在使用 public ServerSocket (int port, int backlog, InetAddress bindAddr)构造方法中 的参数 bindAddr 创建 ServerSocket 对象后, 客户端想要连接到 服务端, 则客户端 Socket 的 构造方法的参数要写上与 ServerSocket 构造方法的参数 bindAddr 相同的 IP 地址, 不然就会 出现异常 。

4.绑定到指定的 Socket 地址

public void bind (SocketAddress endpoint)方法的主要作用是将 ServerSocket 绑定到特定的 Socket 地址 (Ip 地址和端口号),使用这个地址与客户端进行通信。 如果地址为 null ,则 系统将挑选一个临时端口和一个有效本地地址来绑定套接字。

该方法的使用场景就是在使用 ServerSocket 类的无参构造方法后想指定本地端口 。

SocketAddress 类是抽象类,有 1 个子类 InetSocketAddress,它提供不可变对象,供套接字用于绑定 、 连接或用作返回值。 注意:InetAddress 类代表 IP 地址,而 In etSocketAddress 类代表 Socket 地址。

InetSocketAddress 类有 3 个构造方法,说明如下 :

1 )构造方法 public InetSocketAddress (int port)的作用是创建套接字地址,其中 IP 地址 为通配符地址,端口号为指定值。 有效的端口值介于 0 ~ 65535 之间 。 端口号传人 0 代表在 bind 操作中随机挑选空闲的端口

通配符是一个特殊的本地 IP 地址 。 它通常表示 “任何”,只能用于 bind 操作 。

2 )构造方法 public InetSocketAddress (String hostname, int port)的作用是根据主机名和 端口号创建套接字地址。 有效的端口值介于 0 ~ 65535 作中随机挑选空闲的端口 。之间 。

3 )构造方法 public InetSocketAddress (lnetAddress addr, int port)的作用根据 IP 地址和 端口号创建套接字地址。 有效的端口值介于 0 ~ 65535 之间 。

InetSocketAddress的2个方法

getHostName()getHostString ()方法的区别

public final String getHostName()方法的作用是获取主机名 。 注意,如果地址是用字面IP 地址创建 的,则 此方法可能触发名称服务反 向 查找, 也就是利用 DNS 服务通过 IP 找到 域名 。

public final String getHostString()方法的作用是返回主机名或地址的字符串形式,

如果它没有主机名 ,则返回 IP 地址。 这样做的好处是不尝试反 向查找 。

5.获取本地SocketAdress 对象以及本地端口

getLoca!SocketAddress()方法用来获取本地的 SocketAddress 对象 ,它返回此Socket 绑定的端点的地址, 如果尚未绑定, 则返回 null。

getLoca!Port()方法用来获取Socket 绑定到 本地的端 口 。

ServerSocket serverSocket = new ServerSocket();
System . out . println ("new ServerSocket()无参构造的端口是”+serverSocket. getLocalPort());
//将输出-1

6.关闭与获取关闭状态 判断 Socket 绑定状态

public void close()方法的作用是关闭此套接字。

public boolean isClosed()方法的作用是返回 ServerSocket 的关闭状态。

public boolean isBound()方法的作用是返回 ServerSocket 的 绑定状态。

7.获得 IP 地址信息

getlnetAddress()方法用来获取 Socket 绑定的本地 IP 地址信息 。 的,则该方法返回 null。

8.Socket 选项 ReuseAddress

public void setReuseAddress(boolean on)方法的作用是启用 /禁用 SO_REUSEADDR 套 接字选项 ,实现端口复用。

关闭 TCP 连接时 ,该连接可能在关闭后 的一段时间内 保持超时状态 (通常称为 TIME_ WAIT 状态或 2MSL 等待状态) 。 对于使用已知套接字地址或端口的应用程序而言,如果存在处于超时状态的连接(包括地址和端口),则应用程序可能不能将套接字绑定到所需的 SocketAddress 上 。

public boolean getReuseAddress()方法的作用是测试是否启用 SO_REUSEADDR。

在调用 Socket 类的 close()方法时·,会关闭当前连接,释放使用的端口,但在操作系统 层面,并不会马上释放当前使用的端口.

什么是 TIME WAIT 状态?

服务端( Server)与客户端( Client)建立 TCP 连接之后,主动关闭连接的一方就会进入 TIME WAIT 状态。 例如,客户端主动关闭连接时,会发送最后 一个 ACK ,然后客户端就会进入 TIME WAIT 状态,再“停留若干时间’,然后进入 CLOSED 状态 。 在 Linux 操作系统中,当在“停留若干时间”段时,应用程序是可以复用呈 TIME WAIT 状态的端口的,这样可提升端口利用率。

image-20200716144345398

image-20200716144356677

9.Socket 选项 ReceiveBufferSize

每个套接口都有一个发送缓冲区和一个接收缓冲区.

SO RCVBBUF 的值用于设置内部套接字接收缓冲区的大小和设置公布到远程同位体的 TCP 接收窗 口的大小

在接受的套接字中,实际被采纳的值必须在accept()方法返回套接字后通过调用 Socket.getReceiveBufferSize()方法进行获取。

对于客户端, SO RCVBUF 选项必须在 connect 方法调用之前设置 ,对于服务端, SO_RCVBUF 选项必须在 bind()前设置。

image-20200716150058192

image-20200716150019208

3.Socket类的使用

1.绑定 bind 与 con nect 以及端口生成的时机

public void bind (SocketAddress bindpoint) 方法 的作用是将套接字绑定到本地地址。 如果地址为 null ,则系统将随机挑选一个空闲的端 口和一个有效的本地地址来绑定套接字。(是客户端自己的ip地址和端口号)

new Socket () 也会自动给自己这一端分配一个端口号,

代码 new Socket ("localhost”, 8888) 来创建客户端的 Socket 井连接 服务端的 8888 端口, 客户端 的 端口并没有指定 , 而是采用 自动分配端 口 号 的算法

客户端的 Socket 中是可以指定使用某个具体的端口的 , 这个功能就 由 bind() 方法提供

public void connect (SocketAddress endpoint)方法的作用就是将此套接字连接到服务端。

注:bind要在connect之前调用

2.连接与超时

public void connect (SocketAddress endpoint, int timeout) 方法的作用是将此套接宇连接到服务端, 并指定一个超时值。 超时值是 0 意味着无限超时 。

3.获得远程端口与本地端口

public int getPort()方法的作用是返回此套接宇连接到的远程端口 。

public int getLocalPort()方法的作用是返回此套接字绑定到的本地端口。

4.获得本地 lnetAddress 地址与本地 SocketAddress 地址

public InetAddress getLocalAddress()方法的作用是获取套接字绑定的本地 InetAddress 地址 信息 。

public SocketAddress getLocalSocketAddress()方法的作用是返回此套接字绑定的端点的 Socket-Address 地址信息 。 如果尚未绑定, 则返回

null 。

5.获得远程 lnetAddress 与远程 SocketAddress()地址

public InetAddress getlnetAddress()方法的作用是返回此套接字连接到的远程 的 InetAddress 地址。 如果套接字是未连接的, 则返回 null。

public SocketAddress getRemoteSocketAddress()方法的作用是返回此套接字远程 端点的SocketAddress 地址, 如果未连接 , 则返回 null 。

6.套接字状态的判断

public boolean isBound()方法的作用是返回套接字的绑定状态 。 如果将套接字成功地绑 定到一个地址,则返回 true。

public boolean isConnected() 方法的作用是返 回套接字的连接状态 。 如果将套接字成功 地连接到服务端,则为 true。

public boolean isClosed()方法的作用是返回 套接字 的关闭状态 。 如果已经关闭了套接 字, 则返回 true

public synchronized void close()方法的作用是关闭此套接字。 所有当前阻塞于此套接字上的 I/0 操作中的线程都将抛出 SocketException。 套接字被关闭后,便不可在以后的网络连接 中使用 ( 即无法重新连接或重新绑定),如果想再次使用套接字, 则需要创建新的套接字。

关闭此套接字也将会关闭该套接字 的 InputStream 和 OutputStream。 如果此套接字有一个与之关联的通道,则关闭该通道 。

7.开启半读与半写状态、

public void shutdownlnput()方法的作用是将套接字的输入流置于“流的末尾 EOF ”,也就是在套接字上调用 shutdownlnput()方法后从套接字输入流读取内容,流将返回 EOF (文件结束符).发送到套接字的输入流的任何数据都将在确认后被静默丢弃。 一端 能读,另 一端不能读,称为半读。

public void shutdownOutput()方法的作用是禁用此套接字的输出流。 对于 TCP 套接字 , 任何以前写入的数据都将被发送,并且后跟 TCP 的正常连接终止序列 。调 用 shutdownOutput()方法后,写入套接字输出流,则该流将抛出 IOException。 一 端能写,另一端不能写,称为半写 。

8.判断半读半写状态

public boolean islnputShutdown()方法 的作用 是返回 是否关 闭 套接字 连接的半读状态 (read-half) 。 如果己关闭套接字 的输入, 则返回 true。

public boolean isOutputShutdown()方法的作用是返回是否关闭 套接字连接的半写状态 (write-half) 。 如果已关闭套接字的输出,则返回 true。

9 Socket 选项 TcpNoDelay(略)

什么是 MSS 呢? MSS (Maximum Segment Size )即最大报文段长 度 。 在 TCP/IP 中,无论发送多少数据,总是要在数据前面加上协议头 , 同时,对方接收到 数据,也需要发送回 ACK 以表示确认。 为了尽可能地利用网 络带宽, TCP 总是希望尽可能 一次发送足够大的数据,此时就可以使用 MSS 来进行设置。 MSS 选项是 TCP/IP 定义的一 个选项, 该选项用于在 TCP/IP 连接建立时 , 收发双方协商通信时每一个报文段所能承载的 最大数据长度,它的计算方式如下 : MSS = MTU - 20 字 节的 TCP 报头 - 20 字节的 IP 报头

在以太网环境下, MSS 值一般就是 1500 - 20 - 20 = 1460 字节 。 TCP/IP 希望每 次都能 够以 MSS (最大尺寸)的数据块来发送数据,以增加每次网络传输的数据量 。

10.Socket 选项 Send BufferSize

SO_SNDBUF 选项是设置发送缓冲区的大小的 。

11.Socket选项 Linger

Socket 中的 SO_LINGER 选项用来控制 Socket 关闭 close()方法时的行为 。 在默认情况 下,执行 Socket 的 close()方法后, 该方法会立即返回, 但底层的 Socket 实际上并不会立即 关闭, 它会延迟一段时间 。 在延迟的时间里做什么呢?是将“发送缓冲区”中的剩余数 据在 延迟的时间内继续发送给对方, 然后才会真正地关闭 Socket 连接。

public void setSoLinger(boolean on, int linger)方法的作用是启用/禁用具有指定逗留时 间(以秒为单位)的 SO LINGER。该设置仅影响套接字关闭 。 参数 on 的含义为是否逗留, 参数 linger 的含义为逗留时间, 单位为秒。

1) on 传入 false,SO LINGER 功能被屏蔽

2) on 传人 true, linger 等于 0 ,当调用 Socket 的 close()方法时,将立即中断连接,也 就是彻底丢弃在缓冲区中未发送完的数据,并且发送一个 RST 标记给对方。

3) on 传人 true , linger 大于 65535 时, linger 值就被赋值为 65535 。

4) on 传入 true , linger 不大于 65535 时, linger 值就是传人的值。

12.Socket 选项 Timeout

13.Socket 选项 OOBlnline

Socket 的选项 SO OOBINLINE 的作用是在套接字上接收的所有 TCP 紧 急数据都将通 过套接字输入流接收。 禁用该选项时(默认), 将悄悄丢弃紧急数据。 OOB ( Out Of Bound,

带外数据)可以理解成是需要紧急发送的数据。

14.Socket 选项 KeepAlive

Socket 选项 so 阻EPALIVE 的作用是在创建了服务端与客户端时,使客户端连接上服务 端。 当设置 so 阻EPALIVE 为阳e 时,若对方在某个时间(时间取决于操作系统内核的设置 )内没有发送任何数据过来 那么端点都会发送一个 ACK 探测包到对方,探测双方的 TCP/IP 连 接是否有效(对方可能断电,断网) 。 如果不设置此选项,那么 当客户端着机时,服务端永远 也不知道客户端岩机了,仍然保存这个失效的连接。如果设置了 比选项,就会将此连接关闭 。

public boolean getKeepAlive()方法的作用是判断是否启用 SO_KEEPALIVE 选项 。

public void setKeepAlive(boolean on)方法的作用是设置是否启用 SO_KEEPALIVE 选 项 。 参数 on 代表是否开启保持活动状态的套接字。

该选项在 实际软件开发中并不是常用的技术 ,判断连接是否正常时, 较常用的办法是启动 1 个线程, 在线程中使用轮询嗅探的方式来判断连接是否为正常 的状态 。

15 Socket 选项 TrafficClass

IP 规定了以下 4 种服务类型,用来定性地描述服务的质量。

1 ) IPTOS LOWCOST ( Ox0 2 ) : 发送成本低。

2 ) IPTOS R ELIAB ILITY ( Ox04 ) : 高可靠性,保证把数据可靠地送到目的地。

3 ) IPTOS_THROUGHPUT ( Ox08 ) : 最高吞吐量,一次可 以接收或者发送大批量的数据。

4) IPTOS LOWDELAY ( OxlO ): 最小延迟,传输数据的速度’快,把数据快速送达目的地。 这 4 种服务类型还可以使用 “或”运算进行相应 的组合 。

4.基于 UDP 的 Socket 通信

注意, 在使用 UDP 实现 Socket 通信时一定要使用两台真机, 不要使用虚拟机, 不然会出现 UDP 包无法发送的情况 。

UDP (User Datagram Protocol ,用户数据报协议)是一种面向无连接的传输层协议, 提

供不可靠的信息传送服务 。 无连接是指通信时服务端与客户端不需要建立连接, 端,对方获取数据包再进行数据的处理。

直接把数据包从一端发送到另 一UDP 是“不可靠的”, 是指该协议在网络环境不好的情况下, 会丢失数据包, 因为没有 数据包重传的功能, 另外它也不提供对数据包进行分组 、 组装, 以及不能对数据包进行排 序,这些都是它和 TCP 最主要的区别 。 使用 UDP 发送报文后, 是无法得知其是否安全, 以 及是否完整地到达目的地的 。

UDP 将网络数据流量压缩成数据包的形式, 一个典型的数据包就是一个二进制的数据传输 单位, 每一个数据包的前 8 个字节用来包含报头信息, 剩余字节则用来包含具体的传输数据。

因为 UDP 报文没有可靠性保证 、 没有顺序保证, 以及没有流量控制等功能, 所以它可靠性较差 。 但是,正因为 UDP 的控制选项较少,在数据传输过程中延迟小 、数据传输效率 高,因而适合对可靠性要求不高的应用程序 。

在选择使用某种协议的时候,选择 UDP 必须要谨慎,因为在网络质量不好的情况下, UDP 的数据包丢失的情况会比较严重,但正是因为它是无连接型协议,因而具有资源消耗小、处理速度快的优点 。 通常音频 、 视频和普通数据在传送时使用 UDP 较多 ,因为它们 即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响,如视频聊天时,丢失某些帧对聊天效果影响不大。

TCP 中包含了专门的传递保证机制,来确保发送的数据能到达对端,并且是有序 的 。

UDP 与 TCP 不同, UDP 并不提供数据传送的保证机制,如果在从发送方到接收方的传递过 程中出现数据报的丢失,协议本身并不能做出任何检测或提示,因此,经常把 UDP 称为不可靠的传输协议。 另外,相对于 TCP, UDP 的另外一个不 同之处是不能确保数据的发送和接收的顺序 。

TCP 与 UDP 各有利弊,在不同的场景要使用不同的技术 。

1.使用 UDP 实现 Socket 通信

使用 UDP 实现 Socket 通信时,服务端与客户端都是使用 DatagramSocket 类,传输 的数据要存放在 DatagramPacket 类中 。

DatagramSocket 类表示用来发送和接收数据报包的 套接字 。数据报套接字是包投递 服务的发送或接收点 。

在 DatagramSocket 上总是启用 UDP 广播发送 。 为了接收广播包,应该将 DatagramSocket 绑定到通配符地址? 。 在某些实现中,将 DatagramSocket 绑定到一个更加具体的地址时广播包也 可以被接收。

DatagramPacket 类表示数据报包。数据报包用来实现无连接包投递服务 。

DatagramSocket 类中的 public synchronized void receive(DatagramPacket p)方法

  • 作用 是从此套接字接收数据报包 ,此方法在接收到数据报前 一直阻塞。
  • 当此方法返回时, DatagramPacket 的 缓 冲区填充了接收的数 据 。
  • 数据报包也包含发送方的 IP 地址和发送方机器上的端口号。
  • 数据报包对象的 length 字段包含所接收信息的长度 。 如果发送 的信息比接收端 包关联的 byte[]长度长,该信息将被截短。 如果发送信息的长度大于 65507 ,则发送端出现 异常。

DatagramSocket 类中的 public void send(DatagramPacket p)方法

  • 作用是从此套接字发 送数据报包。
  • DatagramPacket 包含的信息有:将要发送的数据及其长度 、 远程主机的 IP 地 址和远程主机的端口号。

DatagramPacket 类中的 public synchronized byte[] getData()方法

  • 作用是返回数据缓冲 区 。
  • 接收到的或将要发送的数据从缓冲区中的偏移量 offset 处开始,持续 length 长度 。

eg:实现的是客户端使用 UDP 将字符串 1234567890 传递到服务端。


2.测试发送超大数据量的包导致数据截断的情况

理论上, 一个 UDP 包最大的长度为 2^16^ - 1 ( 65536 一 1 = 65535 ),因此, IP 包最大的发 送长度为 65 535 。 但是, 在这 65535 之内包含 IP 协议头的 20 个字节, 还有 UDP 协议头的 8 个字节, 即 65535 一 20 - 8 = 65507 ,因此, UDP 传输用户数据最大的长度为 65507 。 如果 传输的数据大于 65507 ,则在发送端出现异常 。

3.Datagram Packet 类中常用 API 的使用

DatagramPacket 类中的 public synchronized void setData(byte[] but) 方法的作用是为此包 设置数据缓冲区 。 将此 DatagramPacket 的偏移量设置为 0 ,长度设置为 buf 的长度 。

DatagramPacket 类中的 public synchronized void setData(byte[] buf, int offset, int length) 方法的作用是为此包设置数据缓冲 区 。 此方法设置包的数据 、 长度和偏移量。

DatagramPacket 类中的 public synchronized int getOffset()方法的作用是返回将要发送或 接收到的数据的偏移量。

DatagramPacket 类中的 public synchronized void setLength(int length)方法的作用是为此包设置长度 。 包的长度是指包数据缓 冲区中将要发送的字节数, 或用来接收数据的包数据缓 冲 区的字节数。 长度必须小于或等于偏移量与包缓冲区长度之和 。

4 使用 UDP 实现单播

要已知对方的ip地址

5 使用 UDP 实现广播

DatagramSocket socket = new DatagramSocket socket = new DatagramSocket() ;
socket.setBroadcast( true ) ;
socket.connect(InetAddress.getByName(”192.168.0.255”),7777) ;
String newString = ” _ 12345 ”; 
byte [] byteArray = newString .getBytes() ; 
DatagramPacket myPacket = new DatagramPacket(byteArray, socket. send (my Packet) ; socket.close() ;

和单播的区别就是connect方法的地址为广播地址

image-20200716155654984

image-20200716155708422

6 使用 UDP 实现组擂

“组播”就是将数据报文让指定的计算机知道。 组播也称为多播 。

如果是发送数据报包 , 则可以不调用 joinGroup() 方法加入多播组 ;如果是接收数据报

包 , 则必须调用 joinGroup() 方法加入多播组 。

socket joinGroup(InetAddress . getByName ( ” 224.0.0socket joinGroup(InetAddress . getByName ( ” 224.0.0.5 ” ));

5 小结

本章主要介绍了使用 ServerSocket 和 Socket 实现 TCP/IP 数据通信,使用 DatagramSocket 和 DatagramPacket 实现 UDP 数据通信,并详细介绍了这些类中 API 的使用,以及全部 Socket Option 选项的特性,同时,分析了 TCP/IP 通信时的“握手”与“挥手”,熟练掌握 这些知识有助于理解网络编程的特性,对学习 ServerSocketChannel 通道起到非常重要的铺 垫作用 。 那么在下一章就要学习选择器与 ServerSocketChannel 通道实现多路复用,深入到 NIO 高性能处理的核心 。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!