gpt4 book ai didi

Java 网络代码不发送

转载 作者:行者123 更新时间:2023-11-29 04:03:55 24 4
gpt4 key购买 nike

我正在编写我的第一个重要的 Java 应用程序,它使用:

  • 网络
  • 图形用户界面
  • 线程

这是一个 IM 程序。当我发送消息时,服务器没有输出它应该输出的内容。很抱歉这个描述太糟糕了,但我不知道如何进一步缩小问题范围。

public class MachatServer {
//snip
public static void sendMessage(int targetId, int fromId, String message) {
ConnectedClient targetClient = getClient(targetId);
// Also runs
System.out.println("Sending message: " + message + "\n\nfrom " + fromId + " to " + targetId);
targetClient.addOutCommand("/message:" + fromId + ":" + message + "\n");
}
}
class ConnectedClient implements Runnable {
public void run() {
String contact;
contact = s.getInetAddress().toString();
System.out.println("Connected to " + contact);
try {
out.write("/connected" + "\n");
out.flush();
String command;
while(true) {
if(shouldExit) {
s.close();
break;
}
if(in.hasNextLine()) {
command = in.nextLine();
commandProcessor.addInCommand(command);
}
Thread.sleep(100);
}
} catch(Exception e) {
e.printStackTrace();
}
}
// snip
public void addOutCommand(String command) {
commandProcessor.addOutCommand(command);
//
// My guess is that the problem is with this method as the next line
// Does not print out.
//
//
System.out.println("" + thisId + " recieved to send: " + command);
}
}
class CommandProcessor implements Runnable {
// snip
public void run() {
String currentCommandIn;
String currentCommandOut;
while(true) {
try {
currentCommandIn = inQueue.poll();
if(currentCommandIn != null) {
System.out.println("Processing: " + currentCommandIn);
String[] commandArr = CommandParser.parseRecievedCommand(currentCommandIn);
if(commandArr[0].equalsIgnoreCase("message")) {
int target = Integer.parseInt(commandArr[1]);
String message = commandArr[2];
// This definetly runs
System.out.println("Message sending to: " + target);
MachatServer.sendMessage(target, this.conId, message);
} else if(commandArr[0].equalsIgnoreCase("quit")) {
// Tell the server to disconnect us.
MachatServer.disconnect(conId);
break;
}
currentCommandOut = outQueue.poll();
if(currentCommandOut != null) {
try {
out.write(currentCommandOut + "\n");
System.out.println(currentCommandOut + "sent");
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
} catch(Exception e) {
e.printStackTrace();
}
public synchronized void addOutCommand(String command) {
if(command != null) {
try {
outQueue.push(command);
} catch(Exception e) {
System.out.println(command);
e.printStackTrace();
}
// Does not print
System.out.println("Ready to send: " + command);
} else {
System.out.println("Null command recieved");
}
//snip
}

完整的源代码位于 my github ,以防我错误地缩小了问题范围。

预期的输出应该是当我远程登录并发送“/message:0:test”时,它应该发送“/message:myid:test”到 ID 为 0 的客户端。实际输出什么都没有。

最佳答案

这可能不是一个完整的答案,但您的代码中存在一些严重的问题可能是导致您出现问题的原因,因此您应该首先解决这些问题。

首先,CommandProcessor.run 中的循环处于忙等待状态,即它一直在运行。您应该使用阻塞操作。此外,inQueueoutQueue 是从两个不同的线程访问的,因此您需要在每次访问时进行同步。我建议使用实现 java.util.concurrent.BlockingQueue 接口(interface)的东西来解决这两个问题。最后,在检查您的完整代码时,您似乎还需要同步访问 ConnedtedClient.shouldExit 字段(我相信您可以使用 `java.util.concurrent.atomic.AtomicBoolean 作为替代但我不确定)。

这可能是您的问题的原因:由于 CommandProcessor.run 没有同步任何东西(或访问任何易变的东西),Java 虚拟机可以假设来自外部的任何东西都不能修改它检查的任何东西,所以理论上,当 run 方法第一次注意到 inQueueoutQueue 都是空的时,它可以优化整个方法什么都没有,因为它可以假设它是唯一可以修改它们的东西。但我不知道这是否真的会在实践中发生,因为 JVM 需要对 LinkedList 实现有相当多的了解,并注意到线程只是在循环中执行这两项检查。但最好始终保持安全,因为这样可以保证您的代码正常工作。

关于Java 网络代码不发送,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1582657/

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