많은 클라이언트에 참여할 수있는 서버를 만들었습니다.
그러나 문제가 있습니다.
서버를 시작/중지해야하는 START/STOP 버튼을 추가했습니다. 그러나 코드가 원하는대로 작동하지 않습니다. 연결이 닫히지 않고 코드가 IOException "Server is this"(ServerLogic 부분)로 이동합니다.
클라이언트는 여전히 서버에 연결할 수 있습니다.자바 : 예외없이 서버를 중지하는 방법 (소켓 닫기)
서버 LOGIC
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;
}
}
클라이언트 가입자 (안이 켜지지 코드가 제거되었습니다) START/STOP에게 내가 놓친 무엇
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);
}
}
});
을 처리
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
}
}
}
버튼?
예외없이 올바르게 연결을 종료하는 방법은 무엇입니까?
소켓을 닫기 전에 모든 클라이언트에게 닫기 요청을하거나 서버의 소켓을 닫기 만하면 충분합니까?
감사합니다.
예외 스택 추적을 추가 하시겠습니까? –
물론. 미안, 잊어 버렸어. – rainbow
accept() 메서드에있는 ServerSocket을 닫으면 * 물론 accept() 메서드는 예외로 중단됩니다. 차단 방법은 일반적으로 중단됩니다. 예외를 잡아야하고 catch 블록 내에서 소켓이 닫혀 졌기 때문에 예외가 던져 졌는지 결정할 필요가있다 * 또 다른 이유가있는 경우 *. 예를 들어 catch 블록에서 isClosed()를 사용하면됩니다. – Durandal