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的地址和端口?
通过getInetAddress
和getPort
方法获取。
InetAddress remoteAddress = socket.getInetAddress();
int remotePort = socket.getPort();
18. 如何获取本地Socket的地址和端口?
通过getLocalAddress
和getLocalPort
方法获取。
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发送文件?
使用FileInputStream
和OutputStream
发送文件。
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接收文件?
使用InputStream
和FileOutputStream
接收文件。
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的证书验证?
使用SSLSocket
和SSLContext
处理证书验证。
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();