我正在创建一个简单的聊天服务器,并且只是在每个连接都在新线程上运行。
旧版本为服务器启动了一个单独的线程,它执行了一个while循环,当发送停止消息然后关闭套接字时它会停止。
新版本永远循环,并为每个新连接创建一个新线程。现在我无法关闭套接字连接。
如果您按一个键并且主线程停止,则插座保持打开状态。因此,当我再次运行程序时,我需要更改套接字号。
服务器代码
while(true)
{
///////////////////////////////////////////////////
// get a new connection
///////////////////////////////////////////////////
System.out.println("Aceepting connections on port 1030 \r");
try{
// Get New Connection
// wait for ever on accepting new connections
server.setSoTimeout(0);
connection=server.accept();
cConnection thread = new cConnection("thread3", connection);
} catch(IOException ec)
{
System.out.println(ec.getMessage());
}
}
启动服务器的代码
现在每条消息都进入一个新线程,所以我不能告诉它停止和关闭套接字。
答案 0 :(得分:2)
您需要提供一个必须全局可访问的标志,因此当某个客户端想要停止服务器然后更改变量时会停止该bucle。例如:
class YourServer {
private static boolean execute = true;
public static synchronized void stop() {
execute = false;
}
public void yourMethod() {
while(execute) {
// implement your server here
}
}
}
当客户端发送命令STOP时,您必须执行
YourServer.stop();
答案 1 :(得分:0)
如果你想要一个停止命令来停止服务器,你可以调用System.exit()强制程序存储或只关闭server
可能就是你所需要的。
答案 2 :(得分:0)
考虑到你的问题,我明白了一件事,因为你要放
while(true),所以你的控件总是卡在connection = server.accept();正在寻找新的连接。因此,为了停止套接字,您需要首先找到一种方法来停止循环中的循环。你可以设置一个变量,比如(int clientsConnected)来检查客户端的数量,当零停止while循环时。所以你可以停止你的插座。
下面是我的客户端示例代码,它正在执行关闭套接字的相同操作。 希望这能解决您的问题。
class GetNamesFromServer implements Runnable
{
private Socket sForName, sForId;
private BufferedReader in, inForName, inForId;
private PrintWriter outForName, outForId;
private static String clientNames;
public GetNamesFromServer(Socket s1, Socket s2)
{
sForName = s1;
sForId = s2;
}
public void run()
{
try
{
outForName = new PrintWriter(sForName.getOutputStream(), true);
outForName.println(Client.clientName);
System.out.println("Send Name : " + Client.clientName);
outForName.flush();
}
catch(IOException e)
{
System.err.println("Error sending Name to the Server.");
}
try
{
inForId = new BufferedReader(new InputStreamReader(sForId.getInputStream()));
Client.clientId = (inForId.readLine()).trim();
System.out.println("Client ID is : " + Client.clientId);
}
catch(IOException e)
{
System.err.println("Error Receiving ID from Server.");
}
try
{
inForName = new BufferedReader(new InputStreamReader(sForName.getInputStream()));
while (true)
{
clientNames = inForName.readLine();
if (clientNames != null && clientNames != "")
{
clientNames = clientNames.substring(1, clientNames.length() - 1);
System.out.println("Names Received : " + clientNames);
String[] names = clientNames.split(", ");
Client.nameClients.clear();
for (String element: names)
Client.nameClients.add(element);
Client.nPane.setText("");
int size = Client.nameClients.size();
System.out.println("Size of list : " + size);
for (int i = 0; i < size; i++)
{
String name = Client.nameClients.get(i);
String colour = Character.toString(name.charAt(0));
name = name.substring(1, name.length()) + "\n";
appendToNamePane(name, ReceiveMessages.getColour(Integer.parseInt(colour)), "Lucida Console");
}
System.out.println("Clients Online : " + Client.nameClients);
}
int index = Client.nameClients.indexOf(Client.clientId + Client.clientName);
**if (index == -1)
{
sForName.close();
break;
}**
}
}
catch(IOException e)
{
System.err.println("Error Receiving Names of Clients from Server");
}
}
新版本:
您可以为可以连接的最大客户端数量添加上限,一旦到达您的while循环将不会转到connection = server.accept();
,因此当他们完成聊天(一段时间后),即totalClients = 0时,您也可以停止你的套接字,停止程序。
if (totalClients == 0)
{
socket.close();
serverSocket.close();
}
此致