出于学习目的,我正在编写一个 Java TCP 服务器。这被包装到自己的类中,如 SyteTCPServer
,它使用 ServerSocket
处理连接逻辑。这是一个学校项目,良好的代码实践非常重要。
它被放在自己的类中的原因是因为有一个特定的应用程序级协议(protocol)。该类(class)是一个更大项目的一部分。
当谷歌搜索时,我只发现人们把所有的ServerSocket
及其直接在 main 方法内部的伴随逻辑。我不确定这是否是 OOP 的正确选择?
我的SyteTCPServer
有一个简单的Start()
和Stop()
方法,它隐藏了使用 ServerSocket
的实现,处理客户等.
但是,我有点困惑,因为对于很多网络功能,IntelliJ 会警告我捕获 IOException。接受客户端可能会抛出 IOException,因此可以获得所述客户端的输出流,writeBytes
也可能如此。 ,...你明白我的意思。
在抽象的背景下,我如何最好地处理这些异常?我写一个throws IOException
方法旁边,制作上层代码try...catch
SyteTCPServer.Start
?
此外,如果发生任何异常,整个服务器是否应该停止,或者我是否“隐藏”其中一个客户端未正确连接的事实?或者,当客户端连接失败时,我应该触发一个事件吗?我真的不知道..
由于 UI/核心代码分离,当像瘟疫一样发生异常时,我也会避免编写输出。
我希望这些问题不是太多。
这是我的启动方法的示例,其中抛出 IOException:
public void Start() throws IOException {
this.listenSocket = new ServerSocket(this.port);
Listen();
}
最佳答案
我认为区分可能收到的不同 IOException 很重要。例如,这是创建新连接时的异常还是连接已建立时的异常,这是否是某种预期的错误?最简单的方法就是阅读 documentation并根据具体发生的情况处理错误:
用于构建服务器套接字:
public ServerSocket(int port) throws IOException
- IOException - if an I/O error occurs when opening the socket.
- SecurityException - if a security manager exists and its checkListen method doesn't allow the operation.
- IllegalArgumentException - if the port parameter is outside the specified range of valid port values, which is between 0 and 65535, inclusive.
接受连接:
public Socket accept() throws IOException
- IOException - if an I/O error occurs when waiting for a connection.
- SecurityException - if a security manager exists and its checkAccept method doesn't allow the operation.
- SocketTimeoutException - if a timeout was previously set with setSoTimeout and the timeout has been reached.
- IllegalBlockingModeException - if this socket has an associated channel, the channel is in non-blocking mode, and there is no connection ready to be accepted
等等。
关于在哪里捕获异常:这也取决于您希望服务器在特定情况下执行的操作。但总的来说,捕获“预期”错误并立即处理它们,但将非故意错误扔到更高的级别。
我的意思是:
public void foo() throws IOException {
try {
serverSocket = new ServerSocket(PORT);
} catch (IOException e) {
// Port is in use -> perhaps retry on another port
// If things fail, throw exception anyway
} finally {
if (!serverSocket.isClosed()) {
try {
serverSocket.close();
} catch (IOException e) {
// This exception is to be taken care of internally, not thrown
}
}
}
}
另请注意,这不仅适用于服务器端,也适用于客户端。
祝你编写服务器好运!
关于Java TCP 服务器类抽象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36112810/