1、目的
- 传播交流信息
- TCP:打电话
- UDP:发短信
2、通信协议:
- http
- TCP/IP簇:三次握手(aba),四次挥手(abba)
- https
3、IP与端口
1.IP地址类:InetAddress、InetSocketAddress
InetAddress inetAddress1 = InetAddress.getLocalHost();
InetAddress inetAddress2 = InetAddress.getByName("");
inetAddress1.getHostName(); //计算机名
inetAddress2.getHostAddress(); //IP地址
2.端口
-
单个协议下,端口号不能冲突
-
公有端口0-1023
- HTTP:80
- HTTPS:443
- FTP:21
- Telent:23
-
程序注册端口:1024-49151
- MySQL:3306
- ORACLE:1521
-
端口查看的dos命令:
netstat -ano #查看所有端口 netstat -ano |findstr 1521 #查看1521这个端口
4、UDP编程实例
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
//使用UDP通信实现接收多条消息,并可以同时接收多个客户端的消息
public class ReceiveDemo02 {
public static void main(String[] args) throws IOException {
System.out.println("----服务端启动----");
//创建接收端的Socket对象,并配置监听端口,端口10000与发送端dp里配置的端口相同
DatagramSocket socket = new DatagramSocket(10000);
//创建数据包对象,配置接收数组、数组大小
DatagramPacket dp = new DatagramPacket(new byte[1024], 1024);
while (true) {
//receive会进行线程阻塞
socket.receive(dp);
//打印接收的数据,对dp.getData()进行一个实际数据大小的截位
System.out.println("收到来自" + dp.getAddress().getHostAddress() + "的消息:" + new String(dp.getData(), 0, dp.getLength()));
}
//释放资源
//socket.close();
}
}
import java.io.IOException;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
//使用UDP通信实现发多条消息
public class SendDemo02 {
public static void main(String[] args) throws IOException {
System.out.println("----客户端启动----");
Scanner scanner = new Scanner(System.in);
//创建发送端的Socket对象,系统会随机分配一个端口号
DatagramSocket socket = new DatagramSocket();
while (true){
System.out.println("请输入要发送的内容:");
String next = scanner.next();
if(next.equals("exit")){
//释放资源
socket.close();
return;
}
else {
//定义存放数据的数组
byte[] bytes = next.getBytes(StandardCharsets.UTF_8);
//创建数据包对象,配置发送数据、数据长度、对方IP、对方端口
DatagramPacket dp = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("127.0.0.1"), 10000);
//发送数据
socket.send(dp);
}
}
}
}
5、TCP编程实例
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;
//客户端多发消息
public class ClientDemo04 {
public static void main(String[] args) throws IOException {
Scanner scanner = new Scanner(System.in);
//创建Socket,配置服务端IP与端口
Socket socket = new Socket("127.0.0.1", 10012);
//调用socket.getOutputStream()获取输出流,并用DataOutputStream进行包装
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
while (true){
System.out.println("请输入要发送的数据:");
String next = scanner.next();
if(next.equals("exit")){
//关闭流
dos.close();
socket.close();
return;
}
else {
//发送数据
dos.writeUTF(next);
}
}
}
}
import java.io.DataInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
//目标:掌握利用线程池优化tcp服务端的方式
public class ServerDemo04 {
public static void main(String[] args) throws IOException {
//创建ServerSocket对象,配置监听端口
ServerSocket serverSocket = new ServerSocket(10012);
//创建线程池
final ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(3, 5, 60, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(10), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
System.out.println("服务端启动成功");
while (true) {
//调用serverSocket.accept();,阻塞线程,等待客户端连接
Socket socket = serverSocket.accept();
System.out.println(socket.getInetAddress().getHostAddress() + ":" + socket.getPort() + "连接成功");
//新建线程处理消息接收
Thread thread = new Thread(() -> {
//获取socket的流数据,并用DataInputStream进行封装
try (DataInputStream dis = new DataInputStream(socket.getInputStream())) {
while (true) {
//打印信息,dis.readUTF()阻塞线程,等待客户端发送消息
System.out.println("收到来自" + socket.getInetAddress().getHostAddress() + ":" + socket.getPort() + "的数据: " + dis.readUTF());
}
} catch (Exception e) {
//当客户端意外断开时,会出现异常,在此进行手动处理
System.out.println(socket.getInetAddress().getHostAddress() + ":" + socket.getPort() + " 断开连接");
}
}, socket.getInetAddress().getHostName());
//将线程添加到线程池,线程池会自己启动线程,不需要单独调用start()
poolExecutor.execute(thread);
/*
//关闭流
dis.close();
socket.close();
serverSocket.close();
*/
}
}
}