gpt4 book ai didi

Java多客户端socket服务器-饥饿

转载 作者:行者123 更新时间:2023-12-01 11:22:28 25 4
gpt4 key购买 nike

考虑以下服务器:

public class TestServer {


public static void main(String[] args) {


String ksName = "/some/path/keystore-server.jks";
char ksPass[] = "password".toCharArray();
char ctPass[] = "pswd".toCharArray();

KeyStore ks;
try {
ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(ksName), ksPass);
KeyManagerFactory kmf =
KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, ctPass);
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(kmf.getKeyManagers(), null, null);
SSLServerSocketFactory ssf = sc.getServerSocketFactory();
SSLServerSocket s = (SSLServerSocket) ssf.createServerSocket(SERVER_PORT);

while(true){
SSLSocket sslsocket = (SSLSocket) s.accept();
System.out.println("New Client accepted");
TestThread t = new TestThread(sslsocket);
t.run();
}

} catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException | UnrecoverableKeyException | KeyManagementException ex) {
Logger.getLogger(TotalControlServer.class.getName()).log(Level.SEVERE, null, ex);
}
}

}

上面是一个接受多个客户端的简单服务器:在接受新连接后,立即分派(dispatch)一个新线程(TestThread)以处理客户端传入请求。这是 TestThread 的代码:

public class TestThread implements Runnable {

SSLSocket sslsocket;

public TestThread(SSLSocket sslsocket) {
this.sslsocket = sslsocket;
}

@Override
public void run() {

ObjectInputStream is = null;
ObjectOutputStream os = null;
try {
is = new ObjectInputStream(sslsocket.getInputStream());
os = new ObjectOutputStream(sslsocket.getOutputStream());

while(true){
String p = (String) is.readObject();
System.out.println("We got: " + p);

os.writeObject(p.concat(p));
os.flush();

}//while

} catch (IOException ex) {
Logger.getLogger(CmdLineService.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(CmdLineService.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
is.close();
os.close();
this.sslsocket.close();
} catch (IOException ex) {
Logger.getLogger(CmdLineService.class.getName()).log(Level.SEVERE, null, ex);
}
}
}//run

}

很简单,它只是无限循环地读取字符串并将其与自身的连接发回。

客户端也相当简单:

public class TestClient {


public static void main(String[] args) {

System.setProperty("javax.net.ssl.trustStore" , "/path/keystore-client.jks") ;
ObjectOutputStream os = null;
ObjectInputStream is = null;
SSLSocket sslsocket = null;

try {
SSLSocketFactory f = (SSLSocketFactory) SSLSocketFactory.getDefault();
sslsocket = (SSLSocket) f.createSocket("localhost", SERVER_PORT);

sslsocket.startHandshake();
System.out.println("Authentication done");

os = new ObjectOutputStream(sslsocket.getOutputStream());
is = new ObjectInputStream(sslsocket.getInputStream());


BufferedReader b = new BufferedReader(new InputStreamReader(System.in));
boolean exit = false;
while(!exit){
System.out.print("> ");
String line = b.readLine();
os.writeObject(line);
os.flush();

String s = (String) is.readObject();
System.out.println(s);

}//while

} //main
catch (IOException ex) {
Logger.getLogger(TotalControlCmdClient.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(TestClient.class.getName()).log(Level.SEVERE, null, ex);
} finally {

try {
is.close();
sslsocket.close();
} catch (IOException ex) {
Logger.getLogger(TestClient.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

只是无限循环地发送字符串和读取字符串。

这对于一个客户端来说效果很好。但是,如果我启动另一个客户端,它就无法连接!我似乎面临某种线程匮乏问题..

我该如何解决这个问题?

最佳答案

原因很简单:你永远不会启动第二个监听器线程:

   while(true){                
SSLSocket sslsocket = (SSLSocket) s.accept();
System.out.println("New Client accepted");
TestThread t = new TestThread(sslsocket);
t.run();
}

调用run()不会启动线程,这是使用start()完成的。因此,主线程正在处理 run() 方法的内容,并且由于它很忙,因此您无法使用第二个客户端进行连接。

t.run()更改为t.start,一切都会好起来的。

关于Java多客户端socket服务器-饥饿,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31074889/

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