简介

Java网络编程是指使用Java语言进行网络通信的一系列技术和API。通过Java网络编程,我们可以创建网络应用程序,实现不同主机之间的数据传输和通信。

Java提供了丰富的网络编程API,其中最常用的是基于Socket的传统网络编程和基于NIO的非阻塞网络编程。

基本概念

在进行Java网络编程时,需要了解以下基本概念:

  1. IP地址:IP地址是用于标识网络上的设备(计算机、路由器等)的唯一标识符。IP地址分为IPv4和IPv6两种格式。

  2. 端口号:端口号用于标识应用程序在设备上的网络接口。有效的端口号范围是0到65535,其中0到1023是被保留的系统端口,应用程序通常使用大于1023的端口号。

  3. Socket:Socket是网络编程的基本概念之一,它代表一个网络连接的一端。通过Socket,应用程序可以进行数据的读取和写入。

  4. 服务器端和客户端:在网络通信中,有两种角色:服务器端和客户端。服务器端监听指定的端口,并等待客户端的连接请求;客户端通过指定服务器的IP地址和端口号来连接服务器。

网络编程知识点

以下是一些常见的网络编程知识点:

  1. TCP和UDP:TCP(Transmission Control Protocol)和UDP(User Datagram Protocol)是两种常见的网络传输协议。TCP提供可靠的、面向连接的通信,而UDP提供不可靠的、面向无连接的通信。

  2. Socket编程:Socket编程是基于TCP和UDP的网络编程的基础。通过Socket,可以建立连接、发送和接收数据。Java提供了SocketServerSocket类来实现Socket编程。

  3. 多线程服务器:在服务器端,通常需要使用多线程来处理多个客户端的连接请求。每个客户端连接都可以使用一个独立的线程来处理。

  4. URL和URLConnection:Java提供了URLURLConnection类来进行URL的操作和数据的传输。通过URL和URLConnection,可以进行HTTP连接、读取Web页面内容等操作。

Socket编程

Socket编程是Java网络编程的基础,它提供了一种在网络上进行数据传输的机制。Socket是两台计算机之间建立的通信端点。

在Java中,可以使用java.net包中的Socket类和ServerSocket类来实现Socket编程。

Socket类

Socket类表示一个客户端的Socket,用于与服务器建立连接并进行通信。

常见Socket类方法
  • Socket(String host, int port): 创建一个Socket实例,连接到指定主机和端口。

  • SocketInetAddress host, int port): 创建一个Socket实例,连接到指定 IP 地址和端口。

  • InputStream getInputStream(): 获取与此Socket关联的输入流,用于从服务器接收数据。

  • OutputStream getOutputStream(): 获取与此Socket关联的输出流,用于向服务器发送数据。

  • void connect(SocketAddress host, int timeout): Socket实例连接到服务器,并指定一个超时值。

  • InetAddress getInetAddress(): 返回Socket实例连接的地址。

  • int getPort(): 返回Socket实例连接到的远程端口。

  • int getLocalPort(): 返回Socket实例绑定到的本地端口。

  • SocketAddress getRemoteSocketAddress(): 返回Socket实例连接的端点的地址,如果未连接则返回 null。

  • void close(): 关闭Socket连接。

ServerSocket类

ServerSocket类用于在服务器端监听指定的端口,并接受客户端的连接请求。

常见ServerSocket类方法
  • ServerSocket(): 创建一个非绑定ServerSocket实例。

  • ServerSocket(int port): 创建一个ServerSocket实例,监听指定端口。

  • ServerSocket(int port, int backlog, InetAddress address): 使用指定的端口、侦听 backlog 和要绑定到的本地 IP 地址创建一个ServerSocket实例。

  • Socket accept(): 接受一个客户端的连接请求,并返回一个表示客户端连接的Socket实例。

  • int getLocalPort(): 返回ServerSocket实例在其上侦听的端口。

  • void bind(SocketAddress host, int backlog): 将 ServerSocket实例绑定到特定地址(IP 地址和端口号)。

  • void close(): 关闭ServerSocket。

实战案例

下面是一个简单的Socket编程实战案例,展示了一个基于TCP的简单聊天室。

服务器端代码

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
​
public class ChatServer {
    private List<Socket> clients = new ArrayList<>();
​
    public static void main(String[] args) throws IOException {
        ChatServer server = new ChatServer();
        server.start(8888);
    }
​
    public void start(int port) throws IOException {
        ServerSocket serverSocket = new ServerSocket(port);
        System.out.println("Server started on port " + port);
​
        while (true) {
            Socket clientSocket = serverSocket.accept();
            System.out.println("New client connected: " + clientSocket);
​
            clients.add(clientSocket);
​
            new Thread(() -> handleClient(clientSocket)).start();
        }
    }
​
    private void handleClient(Socket clientSocket) {
        try {
            InputStream inputStream = clientSocket.getInputStream();
            OutputStream outputStream = clientSocket.getOutputStream();
​
            byte[] buffer = new byte[1024];
            int bytesRead;
​
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                String message = new String(buffer, 0, bytesRead);
                System.out.println("Received message: " + message);
​
                broadcastMessage(message, clientSocket);
​
                if (message.equalsIgnoreCase("quit")) {
                    break;
                }
            }
​
            clientSocket.close();
            clients.remove(clientSocket);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
​
    private void broadcastMessage(String message, Socket sender) throws IOException {
        for (Socket client : clients) {
            if (client != sender) {
                OutputStream outputStream = client.getOutputStream();
                outputStream.write(message.getBytes());
                outputStream.flush();
            }
        }
    }
}

客户端代码

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
​
public class ChatClient {
    public static void main(String[] args) throws IOException {
        ChatClient client = new ChatClient();
        client.start("localhost", 8888);
    }
​
    public void start(String serverAddress, int serverPort) throws IOException {
        Socket socket = new Socket(serverAddress, serverPort);
        System.out.println("Connected to server: " + socket);
​
        Thread inputThread = new Thread(() -> handleInput(socket));
        inputThread.start();
​
        try {
            InputStream inputStream = socket.getInputStream();
            byte[] buffer = new byte[1024];
            int bytesRead;
​
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                String message = new String(buffer, 0, bytesRead);
                System.out.println("Received message: " + message);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
​
        socket.close();
    }
​
    private void handleInput(Socket socket) {
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            OutputStream outputStream = socket.getOutputStream();
​
            String input;
            while ((input = reader.readLine()) != null) {
                outputStream.write(input.getBytes());
                outputStream.flush();
​
                if (input.equalsIgnoreCase("quit")) {
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

这个简单的聊天室示例展示了基于Socket编程的Java网络编程。服务器端使用ServerSocket监听指定端口,接受客户端连接,并处理客户端发送的消息,并将消息广播给其他客户端。客户端通过Socket连接服务器,并发送和接收消息。