Java Socket面试题

1. 描述Java中Socket的基本工作机制。

Java中的Socket编程涉及客户端和服务器端。服务器端使用ServerSocket监听特定端口,等待客户端连接。客户端使用Socket发起连接到服务器的特定端口。一旦连接建立,双方可以进行数据交换。

// 服务器端
ServerSocket serverSocket = new ServerSocket(port);
Socket clientSocket = serverSocket.accept();

// 客户端
Socket socket = new Socket(serverAddress, port);

2. 如何在Java中创建一个服务器Socket?

使用ServerSocket类并指定端口号创建服务器端Socket。

int port = 1234;
ServerSocket serverSocket = new ServerSocket(port);

3. 如何在Java中创建一个客户端Socket?

使用Socket类并指定服务器的IP地址和端口号创建客户端Socket。

String serverAddress = "127.0.0.1";
int port = 1234;
Socket socket = new Socket(serverAddress, port);

4. 什么是阻塞和非阻塞Socket?

阻塞Socket在等待I/O操作完成时会挂起当前线程,而非阻塞Socket会立即返回,即使I/O操作未完成。

socket.setSoTimeout(1000); // 设置超时时间为1000毫秒,使Socket变为非阻塞

5. 如何在Socket上发送数据?

使用OutputStream从Socket发送数据。

OutputStream os = socket.getOutputStream();
os.write("Hello Server".getBytes());

6. 如何在Socket上接收数据?

使用InputStream从Socket接收数据。

InputStream is = socket.getInputStream();
byte[] buffer = new byte[1024];
int bytesRead = is.read(buffer);

7. 如何关闭Socket连接?

调用Socket的close方法关闭连接。

socket.close();

8. TCP和UDP Socket有什么区别?

TCP提供可靠的、有序的和错误检查的数据流,而UDP提供不可靠的、无连接的数据流。

9. 如何处理Socket的异常?

捕获IOException处理Socket异常。

try {
    socket.close();
} catch (IOException e) {
    e.printStackTrace();
}

10. 如何设置Socket的超时时间?

使用setSoTimeout方法设置读取操作的超时时间。

socket.setSoTimeout(1000); // 设置超时时间为1000毫秒

11. 如何获取Socket的输入流?

通过getInputStream方法获取输入流。

InputStream inputStream = socket.getInputStream();

12. 如何获取Socket的输出流?

通过getOutputStream方法获取输出流。

OutputStream outputStream = socket.getOutputStream();

13. 如何设置Socket的发送缓冲区大小?

使用setSendBufferSize方法设置发送缓冲区大小。

socket.setSendBufferSize(1024);

14. 如何设置Socket的接收缓冲区大小?

使用setReceiveBufferSize方法设置接收缓冲区大小。

socket.setReceiveBufferSize(1024);

15. 如何设置Socket的保持活动选项?

使用setKeepAlive方法设置保持活动选项。

socket.setKeepAlive(true);

16. 如何设置Socket的TCP_NODELAY选项?

使用setTcpNoDelay方法设置TCP_NODELAY选项。

socket.setTcpNoDelay(true);

17. 如何获取远程Socket的地址和端口?

通过getInetAddressgetPort方法获取。

InetAddress remoteAddress = socket.getInetAddress();
int remotePort = socket.getPort();

18. 如何获取本地Socket的地址和端口?

通过getLocalAddressgetLocalPort方法获取。

InetAddress localAddress = socket.getLocalAddress();
int localPort = socket.getLocalPort();

19. 如何在服务器Socket上接受客户端连接?

使用accept方法接受客户端连接。

Socket clientSocket = serverSocket.accept();

20. 如何在客户端Socket上连接到服务器?

直接通过构造函数连接到服务器。

Socket socket = new Socket(serverAddress, port);

21. 如何关闭服务器Socket?

调用close方法关闭服务器Socket。

serverSocket.close();

22. 如何绑定Socket到特定的地址和端口?

使用bind方法绑定Socket。

SocketAddress socketAddress = new InetSocketAddress(port);
serverSocket.bind(socketAddress);

23. 如何使用Socket发送文件?

使用FileInputStreamOutputStream发送文件。

FileInputStream fis = new FileInputStream("file.txt");
OutputStream os = socket.getOutputStream();
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
    os.write(buffer, 0, bytesRead);
}
fis.close();
os.close();

24. 如何使用Socket接收文件?

使用InputStreamFileOutputStream接收文件。

InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream("received_file.txt");
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = is.read(buffer)) != -1) {
    fos.write(buffer, 0, bytesRead);
}
fos.close();
is.close();

25. 如何设置Socket的读取超时?

使用setSoTimeout方法设置读取超时。

socket.setSoTimeout(5000); // 设置读取超时为5000毫秒

26. 如何检测Socket是否关闭?

检查isClosed方法的返回值。

boolean isClosed = socket.isClosed();

27. 如何处理Socket的证书验证?

使用SSLSocketSSLContext处理证书验证。

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagers, new SecureRandom());
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(socket, host, port, true);

28. 如何使用Socket进行多线程通信?

为每个客户端连接创建一个新的线程。

while (true) {
    Socket clientSocket = serverSocket.accept();
    new Thread(new ClientHandler(clientSocket)).start();
}

29. 如何使用Socket发送对象?

使用ObjectOutputStream发送对象。

ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
MyObject obj = new MyObject();
oos.writeObject(obj);
oos.close();

30. 如何使用Socket接收对象?

使用ObjectInputStream接收对象。

ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
MyObject obj = (MyObject) ois.readObject();
ois.close();