停止我的TCP Server java时抛出SocketException

时间:2014-12-13 06:15:18

标签: 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");
    }
}

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

1 个答案:

答案 0 :(得分:1)

启动服务器时,调用serverSocket.accept()。此调用会阻塞线程,直到建立连接。通过调用server.stop(),您将在另一个线程中关闭此服务器套接字。 ServerSocket.close()JavaDoc说: Any thread currently blocked in {@link #accept()} will throw a {@link SocketException}.

这就是为什么你得到这个例外。

我认为你可以忽略这个例外。

P.S。 你应该让你的boolean running不稳定。