Skip to content

Netty

ServerSocket 与 Socket

ServerSocket

java
package study.helloworld.bio;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.Objects;

public class BIOServer {

	public static void main(String[] args) throws IOException {
//		server1();
		server2();
	}

	/**
	 * 只能接受单个连接的 ServerSocket
	 * 
	 * @throws IOException
	 */
	private static void server1() throws IOException {
		// 创建一个 ServerSocket,端口号为 8888
		@SuppressWarnings("resource")
		ServerSocket serverSocket = new ServerSocket(8888);

		while (true) {
			// 监听与 ServerSocket 建立的连接并接受它。该方法将阻塞,直到建立连接为止。
			Socket socket = serverSocket.accept();

			handler(socket);
		}
	}

	/**
	 * 可以接受多个连接的 ServerSocket
	 * 
	 * @throws IOException
	 */
	private static void server2() throws IOException {
		// 创建一个 ServerSocket,端口号为 8888
		@SuppressWarnings("resource")
		ServerSocket serverSocket = new ServerSocket(8888);

		while (true) {
			// 监听与 ServerSocket 建立的连接并接受它。该方法将阻塞,直到建立连接为止。
			Socket socket = serverSocket.accept();

			// 新建一个线程专门处理 Socket
			new Thread(() -> {
				try {
					handler(socket);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}).start();
		}
	}

	/**
	 * 处理客户端 Socket
	 * 
	 * @param socket
	 * @throws IOException
	 */
	private static void handler(Socket socket) throws IOException {
		// 与 ServerSocket 建立的连接的地址。如 /192.168.21.150:58942
		SocketAddress remoteSocketAddress = socket.getRemoteSocketAddress();
		System.out.println(remoteSocketAddress.toString());

		// 转成字符流
		BufferedReader in = new BufferedReader(
				new InputStreamReader(socket.getInputStream()));
		PrintWriter out = new PrintWriter(socket.getOutputStream());

		String request, response;
		// 持续读消息
		while (Objects.nonNull(request = in.readLine())) {
			System.out.println(remoteSocketAddress.toString() + " " + request);

			// 如果读到的消息是 Done 就写消息并断开连接
			if (Objects.equals(request, "Done")) {
				response = remoteSocketAddress.toString() + " Processed";
				out.println(response);
				out.flush();

				out.close();
				in.close();
				socket.close();
				break;
			}
		}
	}

}

Socket

java
package study.helloworld.bio;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.Objects;
import java.util.Scanner;

public class BIOClient {

	public static void main(String[] args) throws IOException {
		// 创建一个连接到指定地址的 Socket
		Socket socket = new Socket("0.0.0.0", 8888);

		// Socket 的地址。如 /192.168.21.150:58942
		SocketAddress localSocketAddress = socket.getLocalSocketAddress();
		System.out.println(localSocketAddress.toString());

		// 转成字符流
		BufferedReader in = new BufferedReader(
				new InputStreamReader(socket.getInputStream()));
		PrintWriter out = new PrintWriter(socket.getOutputStream());

		Scanner scanner = new Scanner(System.in);

		String response, request;
		// 持续写消息
		while (true) {
			if (scanner.hasNextLine()) {
				response = scanner.nextLine();
				out.println(response);
				out.flush();

				// 如果写入的消息是 Done 就读消息并断开连接
				if (Objects.equals(response, "Done")) {
					request = in.readLine();
					System.out.println(request);

					in.close();
					out.close();
					scanner.close();
					socket.close();
					break;
				}
			}
		}

	}

}

ServerSocketChannel 与 SocketChannel

Released under the MIT License.