【问题标题】:Java, problem sending a message with socket connectionJava,使用套接字连接发送消息时出现问题
【发布时间】:2011-05-16 01:08:01
【问题描述】:

我的 Java 程序有问题。它在服务器和许多客户端之间有一个套接字连接。这是服务器(涉及问题的部分):

private static ArrayList<ParallelServer> clientConnected = new ArrayList<ParallelServer>();


public Server(int port) {
    this.port = port;
    if (!startServer())
        JOptionPane.showMessageDialog(new JFrame(""),
                "Error!", "ERROR!",
                JOptionPane.ERROR_MESSAGE);
}

private boolean startServer() {
    try {
        server = new ServerSocket(port);
        loadDatabase();
    } catch (IOException ex) {
        ex.printStackTrace();
        return false;
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    return true;
}

public void runServer() {
    while (true) {
        try {
            client = server.accept();
            ParallelServer pServer = new ParallelServer(client);
            clientConnected.add(pServer);
            Thread thread = new Thread(pServer);
            thread.start();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}


public static void sendBroadcast(String username) throws IOException {
    for(int i = 0; i < clientConnected.size(); i++)
        clientConnected.get(i).sendAnswer("@change," + username);
}

并行服务器是:

    private Socket client;
    private InputStreamReader inputstreamreader;
    private BufferedReader bufferedreader;
    private PrintWriter printwriter;

    public ParallelServer(Socket client) {
        this.client = client;
    }

    public void run() {
        try {
            inputstreamreader = new InputStreamReader(client.getInputStream());
            bufferedreader = new BufferedReader(inputstreamreader);
            printwriter = new PrintWriter(client.getOutputStream(), true);
            String lineread = "";

            while (client.isConnected()) {
                lineread = bufferedreader.readLine();
                doCommand(lineread);
            }
        } catch (UnknownHostException unhe) {
        } catch (InterruptedIOException intioe) {
        } catch (IOException ioe) {
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public void sendAnswer(String answer) throws IOException {
        printwriter = new PrintWriter(client.getOutputStream(), true);
        printwriter.println(answer);
        printwriter.flush();
    }

这里是客户端:

private String serverurl = "localhost";
private int serverport = 7777;
private PrintWriter printwriter;
private InputStreamReader inputstreamreader;
private BufferedReader bufferedreader;
private Socket server;

public Client() {
    server = null;
    try {
        server = new Socket(serverurl, serverport);
        server.setSoTimeout(5000);
    } catch (UnknownHostException unhe) {
        System.out.println("UnknownHostException: " + unhe.getMessage());
    } catch (InterruptedIOException intioe) {
        System.out.println("Timeout while attempting to establish socket connection.");
    } catch (IOException ioe) {
        JOptionPane.showMessageDialog(new JFrame(),"Unable to reach the server!","ERROE!",JOptionPane.ERROR_MESSAGE);
    }
}

public String sendCommand(String command) throws IOException {
    if(server == null) {
        try {
            server = new Socket(serverurl, serverport);
            server.setSoTimeout(5000);
        } catch (UnknownHostException unhe) {
            System.out.println("UnknownHostException: " + unhe.getMessage());
        } catch (InterruptedIOException intioe) {
            System.out.println("Timeout while attempting to establish socket connection.");
        } catch (IOException ioe) {
            JOptionPane.showMessageDialog(new JFrame(),"Unable to reach the server!","ERROR!",JOptionPane.ERROR_MESSAGE);
        }
    }
    if(server != null) {
        printwriter = new PrintWriter(server.getOutputStream(), true);
        printwriter.println(command);
        printwriter.flush();
        inputstreamreader = new InputStreamReader(server.getInputStream());
        bufferedreader = new BufferedReader(inputstreamreader);

        return bufferedreader.readLine();
    }
    else
        return "@serverProblem";
}

该程序是一个简单的回合制在线游戏。玩家的回合是通过队列创建的,当玩家通过他的回合时,服务器会发送一条广播消息,上面写着“现在是'玩家 1' 回合”。 (例如)。我的问题是,当客户端收到消息时,它就像添加答案“现在轮到‘玩家 1’了。”到它将收到的下一条消息。在我的例子中:当一个玩家通过他的回合时,他会发送“@passTurn,username”。 ParallelServer 类从队列中轮询它,将其放在队列的底部,向客户端发送“@ok”以告诉它轮到已成功更改,并告诉服务器类发送广播消息。然后,当同一个客户端尝试做进一步的动作时,它会考虑“现在轮到‘玩家 1’”。作为服务器给它的答案。相反,我希望服务器和客户端像往常一样工作,并且当广播消息发出时,客户端会收到通知,而不会产生任何附带影响。 我能做些什么? 谢谢。

【问题讨论】:

  • 您的输出是在控制台还是 IDE 中?另外,您确定您没有查看正在缓冲的上一条消息吗?
  • @Vern:我的输出是一个 IDE。关于缓冲区,它发生这样的事情:客户端发送“@passTurn”->服务器发送“@ok”->客户端接收它->服务器然后发送“@changeTurn,player1”(客户端什么都不做,因为它没有发送消息并且它不等待答案)-> 客户端发送“@otherAction”并读取“@changeTurn,player1”作为答案。
  • 那么,在该消息交换的哪个点它失败了?
  • 我希望客户端检测到“@changeTurn,player1”,但现在它不能检测到,因为它只检测到使用“sendCommand”的类的答案。每个使用它的班级都喜欢:“我发送这个然后我收到这个”。但是对于广播消息,没有“我发送这个”,因为服务器发送它时没有收到客户端的任何命令,所以没有“我收到这个”。即使我将在“readAnswer”(if(...readLine().contains(“changeTurn”))..) 中放置一个“if else”,也不会检测到它,因为任何类都没有调用“readAnswer” (客户端不知道会发送“@changeTurn”)。
  • 既然如此,这听起来更像是你需要改变你的消息传递机制。此外,您可能想要查看我在下面的回复中建议的非阻塞双向消息。文字太多,无法发表评论。

标签: java sockets client message


【解决方案1】:

您的双向消息传递机制应如下所示:

服务器:

Wait on any client InputStream
if (broadcast) 
  broadcast_message()
else 
  process_message()

客户:

Receiving Thread:
Wait on server broadcast

Sending Thread:
Wait on messages to be sent to server from the User Input

这应该可以解决问题:)

希望对您有所帮助。干杯!

【讨论】:

  • 我不能这样写服务器,因为广播消息不是在 InputStream 之后发送的。我尝试按照您的建议组织客户端,创建一个新线程来等待广播消息,但是缓冲阅读器搞砸了(我的想法是从两个不同缓冲阅读器上的同一输入流中读取,但它不起作用) .也许我应该尝试为此目的使用互斥锁。
  • 用一个不断监听服务器的线程完成。使用 if(bufferedreader.isReady()) 并每 3 秒读取一次答案,通信工作正常。无论如何,谢谢你给了我使用两个不同线程的想法! :)
  • 嘿,别担心!很高兴你设法让事情顺利进行,我总是很乐意提供帮助!干杯!
猜你喜欢
  • 2021-07-29
  • 1970-01-01
  • 1970-01-01
  • 2014-12-24
  • 2015-05-17
  • 1970-01-01
  • 1970-01-01
  • 2012-01-14
  • 2012-09-03
相关资源
最近更新 更多