网络模型:
TCP协议,UDP协议
UDP:面向无连接(不用创建连接),在不创建连接的前提下,有可能发生丢包
采用字节进行传输
每个数据包的大小限制在64K以内
不安全(不靠谱连接)
UDP唯一的好处:块
TCP:面向连接,客户端与服务器建立连接时要经历三次握手,采用字节进行数据的传输
TCP较为安全,但是效率比UDP慢
HTTP协议的底层就是采用TCP协议
基于UDP的网络传输
服务端代码如下:
/**
* UDP协议的服务器.
*/
public class UDPService {
public static void main(String[] args) {
System.out.println("服务器正在启动");
try {
//创建一个连接,没有传入IP地址就是本机 127.0.0.1.
DatagramSocket socket = new DatagramSocket(8080);
//接收客户端传递过来的数据.
byte[] bytes = new byte[1024];
DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
//等待客户端发送过来的数据,如果客户端没有建立连接的情况下就会阻塞.
socket.receive(packet);
//获取来源的IP和端口.
System.out.println("IP地址" + packet.getAddress() + "\t端口" + packet.getPort());
//接收数据,转换String字符串.
String str = new String(packet.getData(), 0, packet.getLength());
System.out.println("客户端发送过来的数据" + str);
} catch (Exception e) {
e.printStackTrace();
}
}
}
客户端代码如下:
/**
* UDP协议客户端.
*/
public class UDPClient {
public static void main(String[] args) {
System.out.println("UDP客户端正在启动");
try {
//创建Socket对象.
DatagramSocket socket = new DatagramSocket();
//创建数据包.
String a = "aaaaaaaa";
DatagramPacket packet = new DatagramPacket(a.getBytes(), a.getBytes().length, InetAddress.getByName("127.0.0.1"), 8080);
//发送数据包.
socket.send(packet);
//关闭socket.
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
先启动服务端再启动客户端。
TCP三次握手
SYN报文是建立连接用的
TCP协议中,客户端与服务器建立连接后,客户端突然挂了
答:客户端挂了,服务器会频繁向客户端发送保活机制的报文,如果响应了代表上来了,
达到次数(10)后代码已经挂掉不再发送,客户端挂了就会开始建立下一次连接了。
TCP四次挥手:
当客户端与服务器要断开情况下,两个都断(同时)
FIN报文是断开连接用的
ACK代表收到客户端断开的请求
TCP案例
客户端代码如下
public class TCPClient {
public static void main(String[] args) {
try {
//创建一个连接.
Socket socket = new Socket("127.0.0.1", 8080);
OutputStream outputStream = socket.getOutputStream();
outputStream.write("没穿裤子".getBytes());
} catch (Exception e) {
e.printStackTrace();
}
}
}
服务端代码如下
public class TCPServer {
public static void main(String[] args) {
try {
System.out.println("tcp启动成功");
//创建连接.
ServerSocket socket = new ServerSocket(8080);
//获取客户端请求,如果客户端没有请求的情况下就会堵塞.
Socket accept = socket.accept();
//获取客户端传输数据.
InputStream inputStream = accept.getInputStream();
//读取数据.
byte[] bytes = new byte[1024];
//如果有值返回一个值,如果没有值返回-1.
int read = inputStream.read(bytes);
System.out.println(new String(bytes, 0, read));
} catch (Exception e) {
e.printStackTrace();
}
}
}