Java网络编程基础与实践
Java网络编程基础
1. IP地址
IP地址是网络中设备的唯一标识,用于在互联网中定位设备。在Java中,可以使用InetAddress类来处理IP地址。
import java.net.InetAddress;
import java.net.UnknownHostException;
public class IPAddressDemo {
public static void main(String[] args) {
try {
// 获取本地主机IP
InetAddress localHost = InetAddress.getLocalHost();
System.out.println("本地主机IP: " + localHost);
// 通过主机名获取IP
InetAddress hostByName = InetAddress.getByName("www.example.com");
System.out.println("域名解析IP: " + hostByName);
// 通过IP地址获取主机信息
InetAddress ipAddr = InetAddress.getByName("192.168.1.1");
System.out.println("IP地址规范主机名: " + ipAddr.getCanonicalHostName());
} catch (UnknownHostException e) {
System.err.println("无法解析主机地址: " + e.getMessage());
}
}
}
2. 端口
端口用于标识计算机上运行的特定服务或进程。端口号范围是0-65535,其中0-1023为系统保留端口,1024-49151为注册端口,49152-65535为动态或私有端口。
常用端口示例
- HTTP: 80
- HTTPS: 443
- SSH: 22
- FTP: 21
- MySQL: 3306
- Tomcat: 8080
端口查看命令
# 查看所有端口
netstat -ano
# 查找特定端口
netstat -ano | findstr "8080"
# 查看端口对应的进程
tasklist | findstr "8080"
3. Socket与TCP通信
TCP是一种面向连接的可靠传输协议,通过Socket实现客户端与服务器之间的通信。
TCP客户端实现
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
public class NetworkClient {
public static void main(String[] args) {
Socket clientSocket = null;
OutputStream outputStream = null;
try {
// 1. 创建连接到服务器的Socket
InetAddress serverAddress = InetAddress.getByName("127.0.0.1");
int serverPort = 9999;
clientSocket = new Socket(serverAddress, serverPort);
// 2. 获取输出流并发送数据
outputStream = clientSocket.getOutputStream();
String message = "这是一条来自客户端的消息";
outputStream.write(message.getBytes());
} catch (IOException e) {
System.err.println("客户端错误: " + e.getMessage());
} finally {
// 3. 关闭资源
closeResource(outputStream);
closeResource(clientSocket);
}
}
private static void closeResource(AutoCloseable resource) {
if (resource != null) {
try {
resource.close();
} catch (Exception e) {
System.err.println("关闭资源时出错: " + e.getMessage());
}
}
}
}
TCP服务器实现
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class NetworkServer {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket clientSocket = null;
InputStream inputStream = null;
ByteArrayOutputStream bufferStream = null;
try {
// 1. 创建服务器Socket并监听端口
serverSocket = new ServerSocket(9999);
System.out.println("服务器已启动,等待客户端连接...");
// 2. 接受客户端连接
clientSocket = serverSocket.accept();
System.out.println("客户端已连接: " + clientSocket.getInetAddress());
// 3. 获取输入流并读取数据
inputStream = clientSocket.getInputStream();
bufferStream = new ByteArrayOutputStream();
byte[] dataBuffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(dataBuffer)) != -1) {
bufferStream.write(dataBuffer, 0, bytesRead);
}
// 4. 处理接收到的数据
String receivedMessage = bufferStream.toString();
System.out.println("收到客户端消息: " + receivedMessage);
} catch (IOException e) {
System.err.println("服务器错误: " + e.getMessage());
} finally {
// 5. 关闭所有资源
closeResource(bufferStream);
closeResource(inputStream);
closeResource(clientSocket);
closeResource(serverSocket);
}
}
private static void closeResource(AutoCloseable resource) {
if (resource != null) {
try {
resource.close();
} catch (Exception e) {
System.err.println("关闭资源时出错: " + e.getMessage());
}
}
}
}
4. UDP通信
UDP是一种无连接的传输协议,类似于发送短信,不需要建立连接,但需要知道对方的地址。
UDP发送端
import java.net.*;
public class UDPSender {
public static void main(String[] args) throws Exception {
// 1. 创建DatagramSocket
DatagramSocket socket = new DatagramSocket();
// 2. 准备发送数据
String message = "这是一条UDP消息";
byte[] sendData = message.getBytes();
// 3. 创建目标地址
InetAddress targetAddress = InetAddress.getByName("localhost");
int targetPort = 9090;
// 4. 创建数据包
DatagramPacket packet = new DatagramPacket(
sendData,
sendData.length,
targetAddress,
targetPort
);
// 5. 发送数据包
socket.send(packet);
// 6. 关闭Socket
socket.close();
}
}
UDP接收端
import java.net.*;
public class UDPReceiver {
public static void main(String[] args) throws Exception {
// 1. 创建DatagramSocket并绑定端口
DatagramSocket socket = new DatagramSocket(9090);
// 2. 创建接收缓冲区
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
// 3. 接收数据包
System.out.println("等待接收消息...");
socket.receive(packet);
// 4. 处理接收到的数据
String receivedMessage = new String(
packet.getData(),
0,
packet.getLength()
);
System.out.println("收到来自 " + packet.getAddress() + " 的消息: " + receivedMessage);
// 5. 关闭Socket
socket.close();
}
}
5. 文件传输
使用Socket实现文件传输功能,客户端发送文件,服务器接收并保存。
文件服务器
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class FileTransferServer {
public static void main(String[] args) throws IOException {
// 1. 创建服务器Socket
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("文件服务器已启动...");
// 2. 等待客户端连接
Socket clientSocket = serverSocket.accept();
System.out.println("客户端已连接: " + clientSocket.getInetAddress());
// 3. 获取输入流
InputStream inputStream = clientSocket.getInputStream();
// 4. 创建文件输出流
FileOutputStream fileOutputStream = new FileOutputStream("received_file.jpg");
// 5. 接收文件数据
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
fileOutputStream.write(buffer, 0, bytesRead);
}
// 6. 发送接收完成通知
OutputStream outputStream = clientSocket.getOutputStream();
outputStream.write("文件接收完成".getBytes());
// 7. 关闭资源
fileOutputStream.close();
inputStream.close();
clientSocket.close();
serverSocket.close();
System.out.println("文件接收完成");
}
}
文件客户端
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
public class FileTransferClient {
public static void main(String[] args) throws IOException {
// 1. 创建Socket连接
Socket socket = new Socket(InetAddress.getByName("localhost"), 8888);
// 2. 创建文件输入流
FileInputStream fileInputStream = new FileInputStream("source_file.jpg");
// 3. 获取Socket输出流
OutputStream outputStream = socket.getOutputStream();
// 4. 发送文件数据
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fileInputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
// 5. 通知服务器发送完成
socket.shutdownOutput();
// 6. 接收服务器响应
InputStream inputStream = socket.getInputStream();
ByteArrayOutputStream responseStream = new ByteArrayOutputStream();
byte[] responseBuffer = new byte[1024];
int responseBytes;
while ((responseBytes = inputStream.read(responseBuffer)) != -1) {
responseStream.write(responseBuffer, 0, responseBytes);
}
System.out.println("服务器响应: " + responseStream.toString());
// 7. 关闭资源
responseStream.close();
inputStream.close();
fileInputStream.close();
outputStream.close();
socket.close();
}
}
6. URL网络资源访问
URL(统一资源定位符)用于定位互联网上的资源,Java提供了URL类来访问网络资源。
URL解析示例
import java.net.MalformedURLException;
import java.net.URL;
public class URLParser {
public static void main(String[] args) throws MalformedURLException {
URL url = new URL("http://example.com:8080/path/to/resource?name=value&key=data");
System.out.println("协议: " + url.getProtocol());
System.out.println("主机名: " + url.getHost());
System.out.println("端口: " + url.getPort());
System.out.println("路径: " + url.getPath());
System.out.println("文件: " + url.getFile());
System.out.println("查询参数: " + url.getQuery());
}
}
URL资源下载
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class URLDownloader {
public static void main(String[] args) throws IOException {
// 1. 创建URL对象
URL fileUrl = new URL("http://example.com/files/document.pdf");
// 2. 打开连接
HttpURLConnection connection = (HttpURLConnection) fileUrl.openConnection();
connection.connect();
// 3. 获取输入流
InputStream inputStream = connection.getInputStream();
// 4. 创建文件输出流
FileOutputStream fileOutputStream = new FileOutputStream("downloaded_document.pdf");
// 5. 下载文件
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
fileOutputStream.write(buffer, 0, bytesRead);
}
// 6. 关闭资源
fileOutputStream.close();
inputStream.close();
connection.disconnect();
System.out.println("文件下载完成");
}
}