1.ip地址(InetAddress类)
- public static InetAddress getLocalHost() 获取本机IP,会以一个inetAddress的对象返回
- public static InetAddress getByName(String host) 根据ip地址或者域名,返回一个inetAddress对象
- public String getHostName() 获取该ip地址对象对应的主机名
- public String getHostAddress() 获取该ip地址对象中的ip地址信息
- public boolean isReachable(int timeout) 在指定毫秒内,判断主机与该ip对应的主机是否能连通
public class Demo1 {
public static void main(String[] args) throws IOException {
InetAddress localHost = InetAddress.getLocalHost();
System.out.println(localHost);
InetAddress inetAddress = InetAddress.getByName("www.baidu.com");
System.out.println(inetAddress);
System.out.println(inetAddress.getHostAddress());
System.out.println(inetAddress.getHostName());
System.out.println(inetAddress.isReachable(1000));
}
}
2.udp-快速入门
客户端:发数据
实现步骤
1. 创建DatagramSocket对象(客户端对象)---->扔韭菜的人
2. 创建DatagramPacket对象封装需要发送的数据(数据包对象)---->韭菜盘子
3. 使用DatagramSocket对象的send方法,传入DatagramPacket对象---->开始抛出韭菜
4. 释放资源使用的API
① DatagramSocket: 客户端、服务端
⑴ public DatagramSocket()创建客户端的Socket对象, 系统会随机分配一个端口号
⑵ public void send(DatagramPacket dp) 发送数据包② DatagramPacket:数据包
public DatagramPacket(byte[] buf, int length, InetAddress address, int port) 创建发出去的数据包对象
public class Client {
public static void main(String[] args) throws IOException {
// 1. 创建DatagramSocket对象(客户端对象)---->扔韭菜的人
DatagramSocket client = new DatagramSocket();
// 2. 创建DatagramPacket对象封装需要发送的数据(数据包对象)---->韭菜盘子
byte[] bytes = "一捆韭菜".getBytes(StandardCharsets.UTF_8);
InetAddress localHost = InetAddress.getLocalHost();
DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, localHost, 8888);
// 3. 使用DatagramSocket对象的send方法,传入DatagramPacket对象---->开始抛出韭菜
client.send(datagramPacket);
// 4. 释放资源
client.close();
}
}
服务端:接收数据(必须用8888)
实现步骤
1.创建DatagramSocket对象并指定端口(服务端对象) ---->接韭菜的人
2.创建DatagramPacket对象接收数据(数据包对象)---->韭菜盘子 3. 使用3.DatagramSocket对象的receive方法,传入DatagramPacket对象 ---->开始接收韭菜
4. 打印结果
5. 释放资源使用的API
DatagramSocket: 客户端、服务端
public DatagramSocket(int port) 创建服务端的Socket对象, 并指定端口号
public void receive(DatagramPacket p) 使用数据包接收数据DatagramPacket:数据包
public DatagramPacket(byte[] buf, int length) 创建用来接收数据的数据包
public int getLength() 获取数据包,实际接收到的字节个数
public class Server {
public static void main(String[] args) throws IOException {
// 1. 创建DatagramSocket对象并指定端口(服务端对象) ---->接韭菜的人
DatagramSocket server = new DatagramSocket(8888);
// 2. 创建DatagramPacket对象接收数据(数据包对象)---->韭菜盘子
byte[] bytes = new byte[64*1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
// 3. 使用DatagramSocket对象的receive方法,传入DatagramPacket对象 ---->开始接收韭菜
server.receive(datagramPacket);
// 获取数据包的ip和端口
String hostAddress = datagramPacket.getAddress().getHostAddress();
int port = datagramPacket.getPort();
// 4. 打印结果
String str = new String(bytes,0, datagramPacket.getLength());
System.out.println("hostAddress="+hostAddress+",port="+port+",str=="+str);
// 5. 释放资源
server.close();
}
}
3.udp-多发多收
客户端: 发数据
实现步骤:
1. 创建DatagramSocket对象(客户端对象)---->扔韭菜的人
2. 创建DatagramPacket对象封装需要发送的数据(数据包对象)---->韭菜盘子
3. 使用DatagramSocket对象的send方法,传入DatagramPacket对象---->开始抛出韭菜
4. 释放资源
使用的API
DatagramSocket: 客户端、服务端
public DatagramSocket()创建客户端的Socket对象, 系统会随机分配一个端口号
public void send(DatagramPacket dp) 发送数据包DatagramPacket:数据包
public DatagramPacket(byte[] buf, int length, InetAddress address, int port) 创建发出去的数据包对象
public class Client {
public static void main(String[] args) throws IOException {
// 1. 创建DatagramSocket对象(客户端对象)---->扔韭菜的人
DatagramSocket client = new DatagramSocket();
// 创建键盘监视对象
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("请输入内容:");
String msg = scanner.next();
// 用户输入exit,就退出输入
if (msg.equals("exit")) {
// 退出
break;
}
// 2. 创建DatagramPacket对象封装需要发送的数据(数据包对象)---->韭菜盘子
byte[] bytes = msg.getBytes(StandardCharsets.UTF_8);
InetAddress localHost = InetAddress.getLocalHost();
DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, localHost, 8888);
// 3. 使用DatagramSocket对象的send方法,传入DatagramPacket对象---->开始抛出韭菜
client.send(datagramPacket);
}
// 4. 释放资源
client.close();
}
}
服务端:接收数据(必须用8888)
实现步骤
1. 创建DatagramSocket对象并指定端口(服务端对象) ---->接韭菜的人
2. 创建DatagramPacket对象接收数据(数据包对象)---->韭菜盘子
3. 使用DatagramSocket对象的receive方法,传入DatagramPacket对象 ---->开始接收韭菜
4. 打印结果
5. 释放资源
使用的API
DatagramSocket: 客户端、服务端
public DatagramSocket(int port) 创建服务端的Socket对象, 并指定端口号
public void receive(DatagramPacket p) 使用数据包接收数据DatagramPacket:数据包
public DatagramPacket(byte[] buf, int length) 创建用来接收数据的数据包
public int getLength() 获取数据包,实际接收到的字节个数
4.tcp-快速入门
①客户端
发数据②实现步骤
1. 创建客户端的Socket对象,请求与服务端的连接
2. 使用socket对象调用getOutputStream()方法得到字节输出流
3. 使用字节输出流完成数据的发送
4. 释放资源:关闭socket管道③使用的API
public Socket(String host , int port) 根据指定的服务器ip、端口号请求与服务端建立连 接,连接通过,就获得了客户端socket
public OutputStream getOutputStream() 获得字节输出流对象
public InputStream getInputStream() 获得字节输入流对象
public class Client {
public static void main(String[] args) throws IOException {
// 1. 创建客户端的Socket对象,请求与服务端的连接
Socket socket = new Socket("127.0.0.1",8888);
// 2. 使用socket对象调用getOutputStream()方法得到字节输出流
OutputStream outputStream = socket.getOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
// 获取用户输入的键盘内容
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("请输入内容:");
String str = scanner.nextLine();
if(str.equals("exit")){
break;
}
// 3. 使用字节输出流完成数据的发送
dataOutputStream.writeUTF(str);
}
// 4. 释放资源:关闭socket管道
dataOutputStream.close();
outputStream.close();
socket.close();
}
}
①服务端 :接收数据
②实现步骤
1. 创建ServerSocket对象,注册服务端端口
2. 调用ServerSocket对象的accept()方法,等待客户端的连接,并得到Socket管道对象
3. 通过Socket对象调用getInputStream()方法得到字节输入流、完成数据的接收
4. 释放资源:关闭socket管道
③使用的API
public ServerSocket(int port) 为服务端程序注册端口
public Socket accept() 阻塞等待客户端的连接请求,一旦与某个客户端成功连接,则返回服务端这边的Socket对象
public class Server {
public static void main(String[] args) throws IOException {
// 1. 创建ServerSocket对象,注册服务端端口
ServerSocket serverSocket = new ServerSocket(8888);
// 2. 调用ServerSocket对象的accept()方法,等待客户端的连接,并得到Socket管道对象
Socket socket = serverSocket.accept();
// 3. 通过Socket对象调用getInputStream()方法得到字节输入流、完成数据的接收
InputStream inputStream = socket.getInputStream();
DataInputStream dataInputStream = new DataInputStream(inputStream);
while(true) {
try {
// 获取客户端发送的数据
String str = dataInputStream.readUTF();
String hostAddress = socket.getInetAddress().getHostAddress();
int port = socket.getPort();
System.out.println("客户端ip:" + hostAddress + "客户端的port:" + port + ",内容:" + str);
}catch (Exception e){
System.out.println("有客户端断开");
break;
}
}
// 4. 释放资源:关闭socket管道
// dataInputStream.close();
// inputStream.close();
// socket.close();
// serverSocket.close();
}
}
5. tcp-多客户端通信
①客户端
发数据②实现步骤
1. 创建客户端的Socket对象,请求与服务端的连接
2. 使用socket对象调用getOutputStream()方法得到字节输出流
3. 使用字节输出流完成数据的发送
4. 释放资源:关闭socket管道③使用的API
public Socket(String host , int port) 根据指定的服务器ip、端口号请求与服务端建立连接,连接通过,就获得了客户端socket
public OutputStream getOutputStream() 获得字节输出流对象
public InputStream getInputStream() 获得字节输入流对象
public class Client {
public static void main(String[] args) throws IOException {
// 1. 创建客户端的Socket对象,请求与服务端的连接
Socket socket = new Socket("127.0.0.1",8888);
// 2. 使用socket对象调用getOutputStream()方法得到字节输出流
OutputStream outputStream = socket.getOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
// 获取用户输入的键盘内容
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("请输入内容:");
String str = scanner.nextLine();
if(str.equals("exit")){
break;
}
// 3. 使用字节输出流完成数据的发送
dataOutputStream.writeUTF(str);
dataOutputStream.flush();
}
// 4. 释放资源:关闭socket管道
dataOutputStream.close();
outputStream.close();
socket.close();
}
}
①服务端
接收数据②实现步骤
1. 创建ServerSocket对象,注册服务端端口
2. 调用ServerSocket对象的accept()方法,等待客户端的连接,并得到Socket管道对象
3. 通过Socket对象调用getInputStream()方法得到字节输入流、完成数据的接收
4. 释放资源:关闭socket管道③使用的API
public ServerSocket(int port) 为服务端程序注册端口
public Socket accept() 阻塞等待客户端的连接请求,一旦与某个客户端成功连接,则返回服务端这边的Socket对象
public class Server {
public static void main(String[] args) throws IOException {
// 创建线程池
ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(
5,
10,
30,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(5),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
// 1. 创建ServerSocket对象,注册服务端端口
ServerSocket serverSocket = new ServerSocket(8888);
// 2. 调用ServerSocket对象的accept()方法,等待客户端的连接,并得到Socket管道对象
while (true) {
Socket socket = serverSocket.accept();
// 创建任务对象
SocketTask socketTask = new SocketTask(socket);
// 把任务交给子线程
// new Thread(socketTask,"线程---").start();
poolExecutor.execute(socketTask);
}
}
}
class SocketTask implements Runnable{
private Socket socket;
public SocketTask(Socket socket){
this.socket = socket;
}
@Override
public void run() {
try {
// 3. 通过Socket对象调用getInputStream()方法得到字节输入流、完成数据的接收
InputStream inputStream = socket.getInputStream();
DataInputStream dataInputStream = new DataInputStream(inputStream);
while (true) {
// 获取客户端发送的数据
try {
String str = dataInputStream.readUTF();
String hostAddress = socket.getInetAddress().getHostAddress();
int port = socket.getPort();
System.out.println(Thread.currentThread().getName() + ",客户端ip:" + hostAddress + "客户端的port:" + port + ",内容:" + str);
}catch (Exception e){
System.out.println("客户单已经断开");
break;
}
}
}catch (Exception e){
// e.printStackTrace();
System.out.println("获取输入内容失败");
}
}
}
6.bs架构
/**
* 服务端
*/
public class MainServer {
public static void main(String[] args) throws IOException {
// 创建处理连接的线程池
ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(
5,
10,
30,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(5),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
// 创建服务端对象
ServerSocket serverSocket = new ServerSocket(8080);
while (true) {
// 循环接收客户端浏览器的连接请求
Socket socket = serverSocket.accept();
// 创建任务类
SocketRunable socketRunable = new SocketRunable(socket);
// 把socket交给子线程
poolExecutor.execute(socketRunable);
}
}
}
/**
* 处理浏览器连接的 任务类
*/
public class SocketRunable implements Runnable{
private Socket socket;
public SocketRunable(Socket socket){
this.socket = socket;
}
@Override
public void run() {
System.out.println("接收到浏览器的请求");
try {
String hostAddress = socket.getInetAddress().getHostAddress();
int port = socket.getPort();
System.out.println(hostAddress+":"+port);
OutputStream outputStream = socket.getOutputStream();
PrintStream printWriter = new PrintStream(outputStream);
printWriter.println("HTTP/1.1 200 OK");
printWriter.println("Content-Type : text/html;charset=UTF-8");
printWriter.println();
printWriter.println("<div style=\"color: black;font-size: 120px;text-align: center\">");
printWriter.println("黑马程序员666");
printWriter.println("</div>");
} catch (IOException e) {
e.printStackTrace();
}
}
}