UDP协议
1. UDP传输协议,该协议称为用户数据报协议(UDP,User Datagram Protocol)。
2. 特点是:无连接,不可靠传输,位于传输层(效率较TCP协议来说是较高的)。
3. 下面是一个基于UDP协议的客户端和服务器端通信的代码,且附上代码详细介绍
客户端代码如下图
package com.itheima_udp;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
public class Client {
public static void main(String[] args) throws Exception {
// 1.创建客户端对象,这里socket作用于客户端,
DatagramSocket socket = new DatagramSocket(8088); // DatagramSocket是一个基于UDP协议客户端对象
Scanner scanner = new Scanner(System.in);
// 通过循环来实现客户端重复的发送信息
while (true) {
System.out.println("请说: ");
String next = scanner.next();
// 判断是否退出客户端
if ("exit".equals(next)) {
System.out.println("退出成功,欢迎下次再来");
socket.close(); // 关闭客户端通信连接,节省通信资源
break;
}
byte[] bytes = next.getBytes();
// 创建一个DatagramPacket对象,这个对象用于存储客户端要输出的信息(需要存储的信息存储在字节数组中)
DatagramPacket packet = new DatagramPacket(bytes, bytes.length, InetAddress.getLocalHost(), 8080);
// 3.发送数据
socket.send(packet);
System.out.println("数据发送完毕");
}
}
}
服务器端代码如下图
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class Server {
public static void main(String[] args) throws Exception {
System.out.println("-------服务端启动-------");
// 创建一个服务器端的对象,这里的socket对象作用于服务器端
DatagramSocket socket = new DatagramSocket(8080); // 这里的参数是为了指定服务器端的端口号
// 字节数组,用于接收来自客户端发送的数据
byte[] bytes = new byte[1024 * 64];
// 创建一个DatagramPacket对象,这个对象用于存储客户端要输出的信息(需要存储的信息存储在字节数组中)
DatagramPacket packet = new DatagramPacket(bytes, bytes.length); // 参数bytes用来存储客户端发来的信息
// 循环,表示重复接受来自客户端的数据
while (true) {
// 接收来自客户端的数据
socket.receive(packet); // 参数packet用来接收数据
int length = packet.getLength();
String s = new String(bytes, 0, length);
System.out.println(s);
System.out.println(packet.getAddress());
System.out.println(packet.getAddress().getHostAddress());
System.out.println(packet.getPort());
}
}
}
TCP协议
1.传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议
2.特点是:面向连接,可靠传输,位于传输层(基于三次握手实现可靠连接)。
3.下面是一个基于TCP协议的客户端和服务器端通信的代码,且附上代码详细介绍
客户端代码如下图
package com.itheima_tcp;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;
public class Client {
public static void main(String[] args) throws Exception {
// 1.创建客户端对象,并且同时请求与服务器端进行连接
Socket socket = new Socket("127.0.0.1", 8888); // 参数1:是要连接服务端的IP地址。参数2:是要连接服务端的端口
// 2.从Socket通信管道中获取字节输出流对象,用于向服务端发送数据
OutputStream outputStream = socket.getOutputStream();
// 3.把低级的字节输出流包装成高级的数据输出流
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("请说: ");
String s = scanner.next();
if ("exit".equals(s)) {
System.out.println("退出成功,欢迎下次使用");
dataOutputStream.close();
socket.close();
break;
}
dataOutputStream.writeUTF(s);
dataOutputStream.flush();
}
}
}
服务端代码如下图
package com.itheima_tcp;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) throws IOException {
System.out.println("服务端启动成功......");
// 1.创建服务器端的ServerSocket对象,同时注册服务器端的端口
ServerSocket serverSocket = new ServerSocket(8888);
// 2.使用serverSocket对象,调用一个accept()方法,等待客户端链接
Socket socket = serverSocket.accept();
// 3.通过socket对象的通信管道获取一个字节输入流
InputStream inputStream = socket.getInputStream();
// 4.把原始的字节输入流包装成高级流
DataInputStream dataInputStream = new DataInputStream(inputStream);
while (true) {
// 5.使用数据输入流读取客户端发送过来的消息
String readUTF = null;
try {
readUTF = dataInputStream.readUTF();
System.out.println(readUTF);
// 获取客户端的IP地址
System.out.println(socket.getRemoteSocketAddress());
} catch (Exception e) {
// 出现异常执行以下操作
System.out.println(socket.getRemoteSocketAddress() + "离线了");
dataInputStream.close();
socket.close();
e.printStackTrace();
}
}
}
}