网络编程的三要素:
测试代码1:获取本机名称和IP地址
package test.client;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
//一台机器可能有多个网络接口和多个IP地址(包括IPv4和IPv6)。
public class LocalInfo {
public static void main(String[] args) {
try {
// 获取本机的名称
String hostName = InetAddress.getLocalHost().getHostName();
System.out.println("本机名称: " + hostName);
// 遍历所有网络接口和IP地址,找到第一个非回环且非IPv6的地址作为“首选”IPv4地址。
// 不同的应用程序或环境可能有不同的“首选”标准。
String preferredIPv4 = getPreferredIPv4Address();
if (preferredIPv4 != null) {
System.out.println("本机首选IPv4地址: " + preferredIPv4);
} else {
System.out.println("未找到首选IPv4地址");
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 尝试获取首选的IPv4地址
private static String getPreferredIPv4Address() throws SocketException {
List<NetworkInterface> networkInterfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface networkInterface : networkInterfaces) {
if (!networkInterface.isLoopback() && networkInterface.isUp()) {
Enumeration<InetAddress> inetAddresses = networkInterface.getInetAddresses();
for (InetAddress inetAddress : Collections.list(inetAddresses)) {
if (!inetAddress.isLoopbackAddress() && inetAddress.getHostAddress().indexOf(':') < 0) {
// 假设第一个非回环且非IPv6的地址是首选的
return inetAddress.getHostAddress();
}
}
}
}
return null; //如果没有配置IPv4地址,或者所有IPv4地址都是回环地址(如127.0.0.1),那么getPreferredIPv4Address() 方法返回null。
}
}
测试代码2:
客户端向服务器端发送数据,服务器为本机。
客户端代码:
package test.client;
import java.io.*;
import java.net.*;
public class TCPClient {
public static void main(String[] args) throws IOException {
String hostName = "localhost"; // 服务器地址
int port = 12345; // 服务器端口号
// 创建Socket实例连接到服务器
Socket socket = new Socket(hostName, port);
// 创建输出流向服务器发送数据
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
// 向服务器发送数据
out.println("Hello, Server!");
// 发送更多数据或关闭连接
// 关闭资源
out.close();
socket.close();
}
}
服务器端代码:
package test.server;
import java.io.*;
import java.net.*;
//异常处理:异常通过throws声明的,在实际应用中,需要更精细的异常处理逻辑,比如使用try-catch块。
//数据编码:使用BufferedReader和PrintWriter,它们默认使用平台的默认字符编码。
//在实际应用中,需要明确指定字符编码,如使用new InputStreamReader(socket.getInputStream(), "UTF-8")。
//资源关闭:使用close()方法关闭流和套接字。
//多线程:如果服务器需要同时处理多个客户端,需要为每个客户端连接创建一个新的线程或使用线程池。
//安全性:在生产环境中,需要考虑使用SSL/TLS来加密通信,保护数据不被窃听或篡改。
//端口号:确保服务器和客户端使用的端口号没有被其他应用程序占用。
public class TCPServer {
public static void main(String[] args) throws IOException {
int port = 12345; // 设置服务器端口号
//服务器创建一个ServerSocket监听来自客户端的连接请求。
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("服务器启动,等待客户端连接...");
// 接受客户端连接
Socket socket = serverSocket.accept();
System.out.println("客户端已连接");
// 从连接中读取数据
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println("接收到客户端数据:" + inputLine);
// 在这里可以对数据进行处理
}
// 关闭资源
in.close();
socket.close();
serverSocket.close();
}
}
运行结果如下:
测试代码2:
客户端向服务器端发送数据,服务器做出响应,服务器为本机。
客户端代码:
package test.client;
import java.io.*;
import java.net.*;
public class TCPClientSend {
public static void main(String[] args) throws IOException {
String hostname = "localhost"; // 服务器地址
int port = 12345; // 服务器端口
try (Socket socket = new Socket(hostname, port)) {
// 向服务器发送数据
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.println("Hello from Client!");
// 读取服务器响应
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println("服务器响应: " + inputLine);
// 只读取一条响应
break;
}
socket.close();
}
}
}
服务器端代码:
package test.server;
import java.io.*;
import java.net.*;
public class TCPServerBack {
public static void main(String[] args) throws IOException {
int port = 12345; // 服务器端口
try (ServerSocket serverSocket = new ServerSocket(port)) {
System.out.println("服务器启动,等待连接...");
// 等待客户端连接
Socket socket = serverSocket.accept();
System.out.println("客户端已连接");
// 读取客户端发送的数据
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println("收到客户端消息: " + inputLine);
// 向客户端发送反馈
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.println("服务器收到: " + inputLine);
//只处理一条消息
break;
}
socket.close();
}
}
}
运行结果如下: