基于分布式通信的基础。
TCPIP、UDP
非阻塞
Multicast:组播
代码演示
分布式架构他就是一个基于网络通信组成的一个超级计算机
经常用到的协议 TCPIP、UDP
TCP/IP:定义了主机如何连接如Inter网以及之间进行通信的一个标准
TCP/IP协议在TCP四层模型上:应用层、传输层、网络层、链路层、物理传输层
OSI七层模型在这个基础之上多了两个模型:
表达层和会话层
3次握手和4次挥手协议:
所谓的三次握手,需要TCP建立三个包确认连接的建立:
(1)第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
(2)第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
(3)第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。
SYN攻击也叫作DDOS:客户端在指定时间内伪造大量不存在的ip地址导致服务器端的连接占满,原本应该给正常请求的数据的server资源被无效的ip连接一直处于SYN_RCVD状态,导致后续正常的请求无法进入请求的队列,造成网络阻塞,系统瘫痪。
4次挥手协议:
全双工:数据通信的双方允许数据向两个方向进行传输
单工:数据传输只支持数据在一个方向上传输
半双工:数据传输允许数据在两个方向上传输,但是在某一时刻,只允许数据在一个方向上传输,有点像换了方向的单工
(1)第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
(2)第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
(3)第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
(4)第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。
UDP:不保证数据一定到达
BIO/NIO
BIO:同步吧阻塞
NIO:同步非阻塞
AIO:异部非阻塞
BIO(阻塞式的io):
典型BIO的代码:
server和socket
server端代码如下:
package com.socketdemo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
try{
serverSocket = new ServerSocket(8888);
Socket socket = serverSocket.accept();
BufferedReader reader = new BufferedReader( new InputStreamReader(socket.getInputStream()) );
System.out.println(reader.readLine());
reader.close();
}catch(Exception e){
e.printStackTrace();
}finally {
serverSocket.close();
}
}
}
client端的代码如下:
package com.socketdemo;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
public class SocketClient {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("localhost",8888);
PrintWriter pw = new PrintWriter( socket.getOutputStream(),true );
pw.println("feifei");
pw.close();
socket.close();
}
}
Multicast(组播):
单播 一对一点对点的通信
广播 发一条消息之后,该区域内的所有人都能够收到消息
组播 介于单播和广播之间的,在组内进行广播,需要指定组的名称
组播的例子:
server端:
package com.Multicast;
import java.io.IOException;
import java.net.*;
import java.util.concurrent.TimeUnit;
public class MulticastServer {
public static void main(String[] args) throws Exception {
InetAddress group = InetAddress.getByName("224.5.6.7");
MulticastSocket socket = new MulticastSocket();
for( int i=0;i<10;i++ ){
String data = "Hello Mic";
byte[] bytes = data.getBytes();
// DatagramPacket 表示的是发送的是 UDP 的数据
socket.send( new DatagramPacket( bytes,bytes.length,group,8888 ) );
TimeUnit.SECONDS.sleep(5);
}
}
}
client端:
package com.Multicast;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;
/**
*
*/
public class MulticastClient {
public static void main(String[] args) throws Exception {
InetAddress group = InetAddress.getByName("244.5.6.7");
try {
MulticastSocket socket = new MulticastSocket();
socket.joinGroup(group);
byte[] buf = new byte[256];
while(true){
DatagramPacket msgPacket = new DatagramPacket( buf,buf.length );
socket.receive( msgPacket );
String msg = new String( msgPacket.getData() );
System.out.println("接收到的数据" + msg);
}
}catch(Exception e){
e.printStackTrace();
}
}
}