gpt4 book ai didi

Java:如何无异常地停止服务器(关闭套接字)?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:05:15 25 4
gpt4 key购买 nike

我做了一个允许加入许多客户端的服务器。
但是我有一个问题。
我添加了应该启动/停止服务器的 START/STOP 按钮。但是代码没有像我想要的那样工作:连接没有关闭并且代码转到 IOException“这是问题”(在 ServerLogic 部分)。
此外,客户端仍然可以与服务器联系。

服务器逻辑

public class ServerLogic
{

private static ServerSocket m_sSocket;
private static Set<ServerSubscriber> m_subscriberList = new HashSet<ServerSubscriber>();
private static boolean m_isServerRun = false;

private static class ServerLogicHolder
{
static final ServerLogic INSTANCE = new ServerLogic();
}


private ServerLogic()
{}


public static ServerLogic getServerLogic()
{
return ServerLogicHolder.INSTANCE;
}


/**
* It starts listening of incoming connections from the clients.
*
* @param port
*/
public void startListening(int port)
{
try
{
if (!m_isServerRun)
{
m_sSocket = new ServerSocket(port);
K6s.getUiServerConsole().addLine(Config.LOG_START);
m_isServerRun = true;
}
else
{
System.out.println(Config.LOG_ERROR1);
}
}
catch (IOException e)
{
System.out.println(Config.LOG_ERROR1);
}

try
{
while (isServerRun())
{
new Thread(new ServerSubscriber(m_sSocket.accept(), K6s.getUiServerConsole())).start();
}
}
catch (IOException e1)
{
/*
java.net.SocketException: socket closed
at java.net.DualStackPlainSocketImpl.accept0(Native Method)
at java.net.DualStackPlainSocketImpl.socketAccept(Unknown Source)
at java.net.AbstractPlainSocketImpl.accept(Unknown Source)
at java.net.PlainSocketImpl.accept(Unknown Source)
at java.net.ServerSocket.implAccept(Unknown Source)
at java.net.ServerSocket.accept(Unknown Source)
at org.czarny.k6s.comm.ServerLogic.startListening(ServerLogic.java:69)
at org.czarny.k6s.gui.K6s$2$1.run(K6s.java:138)
at java.lang.Thread.run(Unknown Source)
*/
}
}


/**
* Just close server's socket.
*/
public void stopListening()
{
if (m_isServerRun)
{
try
{
m_isServerRun = false;
m_sSocket.close();
m_sSocket = null;
}
catch (IOException e)
{
m_isServerRun = true;
System.out.println(Config.LOG_ERROR4);
}
}
}


public HashSet<ServerSubscriber> getSubscriberList()
{
return (HashSet<ServerSubscriber>) m_subscriberList;
}


public boolean isServerRun()
{
return m_isServerRun;
}
}

CLIENT SUBSCRIBER(不需要的代码已被删除)

public class ServerSubscriber implements Runnable
{

private Socket m_socket;
private LogComponent m_serverConsole;
private PrintWriter m_outComm;

private String m_subscriberIP;
private String m_subscriberName;
private String m_subsctiberLogInfo;


ServerSubscriber(Socket socket, LogComponent serverConsole)
{
m_socket = socket;
m_serverConsole = serverConsole;
try
{
m_outComm = new PrintWriter(socket.getOutputStream(), true);
}
catch (IOException e)
{
e.printStackTrace();
}
sendMessage(Config.MSG_HANDSHAKE);
}


/**
* This method runs messages from this subscriber.
*/
public void run()
{
String line;
BufferedReader inComm = null;

try
{
inComm = new BufferedReader(new InputStreamReader(m_socket.getInputStream()));
}
catch (IOException e)
{
m_serverConsole.addLine(Config.LOG_ERROR3);
}

while (ServerLogic.getServerLogic().isServerRun())
{
try
{
//do something here
}
}
}

处理开始/停止的按钮

uiStart.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
if (!ServerLogic.getServerLogic().isServerRun())
{
uiStart.setText(Config.GUI_BTN_STOP);
new Thread(new Runnable()
{
public void run()
{
try
{
ServerLogic.getServerLogic().startListening(Integer.parseInt(uiServerPort.getText()));
}
catch (Exception e)
{
e.printStackTrace();
}
}
}).start();
}
else
{
ServerLogic.getServerLogic().stopListening();
m_uiServerConsole.addLine(Config.LOG_STOP);
uiStart.setText(Config.GUI_BTN_START);
}
}
});

我错过了什么?
如何无一异常(exception)地正确关闭连接?
我应该在关闭套接字之前向所有客户端发送一些要求关闭的消息,还是只关闭服务器上的套接字就足够了?
问候。

最佳答案

I added START/STOP button which should start/stop server. But the code does not work like I want: connection isn't closed

那是因为您要关闭 ServerSocket,而不是已接受的套接字。

and code goes to the IOException "THIS IS PROBLEM" (in ServerLogic part).

这很正常。这里没有问题。

Additionally clients still can contact with server.

现有 客户端可以继续使用他们的现有连接。如果你想关闭它们,请看下一步。无法创建连接。

How to properly close connection without any exceptions?

将它们关闭以进行输入。这将导致读取导致流结束,这应该已经导致相关线程关闭套接字并退出。

Should I just before closing the Socket send to all clients some message with demand of closeure or just closing the Socket on the server should be enough?

关闭套接字就足够了。发送额外的消息不会增加任何值(value)。客户端将从读取中获得通常的流结束指示,或者在写入时获得 IOException: connection reset

关于Java:如何无异常地停止服务器(关闭套接字)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39276549/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com