如何重新打开Java套接字

时间:2009-07-30 08:12:16

标签: java sockets

我正在循环读取Java Socket。

如果读取抛出异常,我想重新打开套接字。

为了测试它,我只需关闭套接字并捕获异常。

当我尝试重新打开套接字时,问题是:

serverSocket = new ServerSocket(port)
socket = serverSocket.accept()

它引发了异常:

java.net.BindException: The socket name is already in use

这是测试的直接问题。但它也可能在生产中出现。

如何通过在异常后打开新的套接字连接来可靠地恢复 已被抛出?

4 个答案:

答案 0 :(得分:5)

如果我误解了你在说什么,我很抱歉。

如果套接字上的read()方法失败,则不会关闭ServerSocket。

您仍然可以在不创建新服务器的情况下调用serverSocket.accept()。我认为这就是你获得BindException的原因。

答案 1 :(得分:4)

您需要创建ServerSocket一次,并将任何接受的套接字传递给其处理程序 - 通常在不同的线程中完成。

你得到的错误是因为你试图在同一个端口上听两次,这是不可能的。

article可能会对您有所帮助。以下是代码示例之一:

public void await() {
    ServerSocket serverSocket = null;
    int port = 8080;
    try {
        serverSocket =  new ServerSocket(port, 1,
        InetAddress.getByName("127.0.0.1"));
    }
    catch (IOException e) {
        e.printStackTrace();
        System.exit(1);
    }

    // Loop waiting for a request
    while (!shutdown) {
        Socket socket = null;
        InputStream input = null;
        OutputStream output = null;
        try {
            socket = serverSocket.accept();
            input = socket.getInputStream();
            output = socket.getOutputStream();

            // create Request object and parse
            Request request = new Request(input);
            request.parse();

            // create Response object
            Response response = new Response(output);
            response.setRequest(request);
            response.sendStaticResource();

            // Close the socket
            socket.close();

            //check if the previous URI is a shutdown command
            shutdown = request.getUri().equals(SHUTDOWN_COMMAND);
        }
        catch (Exception e) {
            e.printStackTrace();
            continue;
        }
    }
}

答案 2 :(得分:2)

我发现工作的是:

  1. 关闭ServerSocket
  2. 创建新的ServerSocket
  3. 关闭ServerSocket后不需要延迟。这是在IBM AIX机器上 - 也许在其他平台上的行为是不同的。

    没有必要关闭套接字。

    我还在Socket中添加了一个超时,以便从连接的另一端恢复失败。这是在启动时和异常时运行的代码:

    if (serverSocket != null) serverSocket.close();
    serverSocket = new ServerSocket(port);
    socket = serverSocket.accept();
    socket.setSoTimeout(TIMEOUT);
    is = socket.getInputStream();
    

    还要感谢提示关闭ServerSocket。这让我走上正轨。还有用于有用的网络编程参考。

答案 3 :(得分:0)

在连接会话期间抛出异常时应关闭套接字。