java - 停止我的 TCP 服务器 java 时抛出 SocketException

标签 java sockets exception tcp

从表单关闭 TCP 服务器时出现此错误。

java.net.SocketException: Socket closed
    at java.net.PlainSocketImpl.socketAccept(Native Method)
    at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:404)
    at java.net.ServerSocket.implAccept(ServerSocket.java:545)
    at java.net.ServerSocket.accept(ServerSocket.java:513)
    at com.hightekjonathan.HomeServer.Server.Start(Server.java:36)
    at com.hightekjonathan.HomeServer.Form$2.run(Form.java:81)
    at java.lang.Thread.run(Thread.java:745)

这是 Server.java:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.*;
import java.util.Enumeration;

public class Server {
    private static ServerSocket serverSocket = null;
    private static Socket socket = null;
    private static DataInputStream dataInputStream = null;
    private static DataOutputStream dataOutputStream = null;

    private static int port = 19586;

    private static boolean running = false;

    public void Start() {
        try {
            System.out.println("Starting Server...");

            serverSocket = new ServerSocket(port);

            System.out.println("Server Started");
            System.out.println("IP Address: " + getIpAddress());
            System.out.println("Listening: " + serverSocket.getLocalPort());

            running = true;
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            System.out.println("Attempting to connect to clients...");
            socket = serverSocket.accept();

            dataInputStream = new DataInputStream(socket.getInputStream());
            dataOutputStream = new DataOutputStream(socket.getOutputStream());

            System.out.println("ip: " + socket.getInetAddress());
            System.out.println("message: " + dataInputStream.readUTF());

            dataOutputStream.writeUTF("connected");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void Stop() {
        if (running) {
            if (socket != null) {
                try {
                    socket.close();
                    socket = null;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            if (dataInputStream != null) {
                try {
                    dataInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (dataOutputStream != null) {
                try {
                    dataOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (serverSocket != null) {
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            running = false;
        }
    }

    private String getIpAddress() {
        String ip = "";
        try {
            Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface.getNetworkInterfaces();
            while (enumNetworkInterfaces.hasMoreElements()) {
                NetworkInterface networkInterface = enumNetworkInterfaces.nextElement();
                Enumeration<InetAddress> enumInetAddress = networkInterface.getInetAddresses();
                while (enumInetAddress.hasMoreElements()) {
                    InetAddress inetAddress = enumInetAddress.nextElement();

                    if (inetAddress.isSiteLocalAddress()) {
                        ip += inetAddress.getHostAddress();
                    }
                }
            }

        } catch (SocketException e) {
            e.printStackTrace();
            ip += "Something Wrong! " + e.toString() + "\n";
        }

        return ip;
    }

    public boolean isRunning() {
        return running;
    }
}

它使用此函数从我的 GUI 表单启动一个新线程:

button.addActionListener(new java.awt.event.ActionListener() {
    public void actionPerformed(java.awt.event.ActionEvent evt) {
         buttonActionPerformed(evt);
    }
);

然后buttonActionPerformed()是这样的:

private void buttonActionPerformed(java.awt.event.ActionEvent evt) {
    if (!server.isRunning()) {
        Runnable r = new Runnable() {
            public void run() {
                server.Start();
            }
        };
        new Thread(r).start();

        button.setText("Stop Server");
        serverStatus.setText("Server: Started");
    } else {
        server.Stop();

        button.setText("Start Server");
        serverStatus.setText("Server: Stopped");
    }
}

仅当我在没有客户端连接的情况下停止服务器时才会出现该错误。但是当客户端连接然后断开连接时,我不会收到该错误。它正确地关闭了它,我只是想确保该错误不会是一个严重的问题,或者是否有一个简单的方法来修复它。

最佳答案

当你启动你的服务器时,你调用serverSocket.accept()。此调用会阻塞线程,直到建立连接为止。通过调用 server.stop() 您将在另一个线程中关闭此服务器套接字。 ServerSocket.close() JavaDoc 说: 当前在 {@link #accept()} 中阻塞的任何线程都会抛出 {@link SocketException}。

这就是您收到此异常的原因。

我认为你可以忽略这个异常。

附注 并且您应该使您的 boolean 运行变得不稳定。

关于java - 停止我的 TCP 服务器 java 时抛出 SocketException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27456124/

相关文章:

java - 当我们有 UrlConnection 时为什么要使用套接字

java - RSA 将字符串转换为 BigInteger

c# - Visual Studio - 从异常返回

java - 有没有办法选择 "unspecified behavior"而不是 ConcurrentModificationException?

java - run方法之外的同步方法

javascript - net socket - 确定当前正在 socket.on ("data"下响应哪个请求)

android - Android客户端错误-java.lang.IllegalStateException : Could not execute method of the activity

c++ - Linux 中的套接字——我怎么知道客户端已经完成?

php - 如何使用 PhpExcel 处理异常?

java - 如何让用户下载我的文件? (Java、MVC、Excel、POI)