gpt4 book ai didi

Java ServerSocket & Sockets 无需等待多线程服务器

转载 作者:太空宇宙 更新时间:2023-11-04 14:51:47 25 4
gpt4 key购买 nike

所以我有一个多线程服务器,数据来回发送正确,但我的写入操作在较慢的连接上停滞。我注意到它是按连接时间进行的。第一个连接的客户端始终首先从服务器接收数据。下一个必须等​​到第一个完成接收,依此类推。我正在寻找的是一个可以向许多客户端发送数据而无需等待客户端完成接收的服务器。我已经阅读了有关 NIO(非阻塞)的内容,但我真的更喜欢保留当前的方法,即为每个客户端使用单独的线程。

这是代码。

服务器:

public class Server implements Runnable {

private Thread thread;
private ServerSocket serverSocket;
private ArrayList<ClientThread> clients;

public Server(int port) throws IOException {
thread = new Thread(this);
clients = new ArrayList<ClientThread>();
serverSocket = new ServerSocket(port);
thread.start();
}

@Override
public void run() {

while (true) {

try {
//Listens to clients connecting.
ClientThread client = new ClientThread(serverSocket.accept());
clients.add(client);
ServerWindow.addText("-- Someone connected!");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

public void broadcast(String data) {
broadcast(data, null);
}

public void broadcast(String data, ClientThread exclude) {

int amount = clients.size();

for (int i = 0; i < amount; i++) {

if (!clients.get(i).equals(exclude)) { //Don't send it to that client.
try {
clients.get(i).broadcast(data);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

}

客户端线程对象:

public class ClientThread implements Runnable {

private Thread thread;
private Socket socket;
private Scanner input;
private PrintWriter output;

public ClientThread(Socket s) throws IOException {
thread = new Thread(this);
socket = s;
socket.setTcpNoDelay(true);
//socket.setSoTimeout(10); //Send little chunk for 10 milliseconds.
input = new Scanner(socket.getInputStream());
output = new PrintWriter(socket.getOutputStream());
thread.start();
}

public void run() {

while (true) {
if (input.hasNext()) {
reciever(input.nextLine());
}
}
}

private void reciever(String data) {
ServerWindow.addText(data);
ServerWindow.server.broadcast(data, this);
}

public void broadcast(String data) throws IOException {
output.println(data);
output.flush();
}

}

最佳答案

您似乎正在从同一线程调用广播方法。

对于刚接触 Java 多线程的用户来说,这是一个常见的陷阱。
广播方法位于 Thread 的子类中这一事实并不意味着它将在该线程上执行

事实上,它将在调用它的线程上执行。将在您创建的 ClientThread 上执行的唯一方法是 run() 以及 run() 在执行时调用的任何方法。如果您希望该线程不仅可以从连接中读取数据,还可以写入数据,则必须修改 run 方法以监听外部命令以开始写入。

关于Java ServerSocket & Sockets 无需等待多线程服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23677567/

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