Knock Knock 带有服务器和 UI 的应用程序

发布于 2025-01-04 14:24:04 字数 7886 浏览 2 评论 0原文

我正在创建一个简单的 Knock Knock 应用程序(套接字编程),其中有一个本地主机服务器和一个客户端。程序很简单,服务器会讲敲门笑话,这就是它应该如何进行,

Server: Knock Knock
Client: Who's there?
Server: Turnip.
Client: Turnip Who?
Server: Turnip the heat.

所以这就是程序应该进行。但问题是我的 GUI 没有显示任何消息。在我的文本区域。这是我的代码。

服务器:

import java.net.*;
import java.io.*;

public class KnockKnockServer {
    public static void main(String[] args) throws IOException {

        ServerSocket serverSocket = null;
        try {
            serverSocket = new ServerSocket(4444);
        } catch (IOException e) {
            System.err.println("Could not listen on port: 4444.");
            System.exit(1);
        }

        Socket clientSocket = null;
        try {
            clientSocket = serverSocket.accept();
        } catch (IOException e) {
            System.err.println("Accept failed.");
            System.exit(1);
        }

        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
        BufferedReader in = new BufferedReader(
                new InputStreamReader(
                clientSocket.getInputStream()));
        String inputLine, outputLine;
        KnockKnockProtocol kkp = new KnockKnockProtocol();

        outputLine = kkp.processInput(null);
        out.println(outputLine);

        while ((inputLine = in.readLine()) != null) {
             outputLine = kkp.processInput(inputLine);
             out.println(outputLine);
             if (outputLine.equals("Bye."))
                break;
        }
        out.close();
        in.close();
        clientSocket.close();
        serverSocket.close();
    }
}

KnockKnockProtocol

import java.net.*;
import java.io.*;

public class KnockKnockProtocol {
    private static final int WAITING = 0;
    private static final int SENTKNOCKKNOCK = 1;
    private static final int SENTCLUE = 2;
    private static final int ANOTHER = 3;

    private static final int NUMJOKES = 5;

    private int state = WAITING;
    private int currentJoke = 0;

    private String[] clues = { "Turnip", "Little Old Lady", "Atch", "Who", "Who" };
    private String[] answers = { "Turnip the heat, it's cold in here!",
                                 "I didn't know you could yodel!",
                                 "Bless you!",
                                 "Is there an owl in here?",
                                 "Is there an echo in here?" };

    public String processInput(String theInput) {
        String theOutput = null;

        if (state == WAITING) {
            theOutput = "Knock! Knock!";
            state = SENTKNOCKKNOCK;
        } else if (state == SENTKNOCKKNOCK) {
            if (theInput.equalsIgnoreCase("Who's there?")) {
                theOutput = clues[currentJoke];
                state = SENTCLUE;
            } else {
                theOutput = "You're supposed to say \"Who's there?\"! " +
                "Try again. Knock! Knock!";
            }
        } else if (state == SENTCLUE) {
            if (theInput.equalsIgnoreCase(clues[currentJoke] + " who?")) {
                theOutput = answers[currentJoke] + " Want another? (y/n)";
                state = ANOTHER;
            } else {
                theOutput = "You're supposed to say \"" + 
                clues[currentJoke] + 
                " who?\"" + 
                "! Try again. Knock! Knock!";
                state = SENTKNOCKKNOCK;
            }
        } else if (state == ANOTHER) {
            if (theInput.equalsIgnoreCase("y")) {
                theOutput = "Knock! Knock!";
                if (currentJoke == (NUMJOKES - 1))
                    currentJoke = 0;
                else
                    currentJoke++;
                state = SENTKNOCKKNOCK;
            } else {
                theOutput = "Bye.";
                state = WAITING;
            }
        }
        return theOutput;
    }
}

客户端。

import java.io.*;
import java.net.*;


public class KnockKnockClient {

    public String fromServer;
    public String fromUser;

    public void Client() throws IOException {

        Socket kkSocket = null;
        PrintWriter out = null;
        BufferedReader in = null;


        try {
            kkSocket = new Socket("127.0.0.1", 4444);
            out = new PrintWriter(kkSocket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream()));
        } catch (UnknownHostException e) {
            System.err.println("Don't know about host: 127.0.0.1");
            System.exit(1);
        } catch (IOException e) {
            System.err.println("Couldn't get I/O for the connection to: 127.0.0.1");
            System.exit(1);
        }

        BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));

        while ((fromServer = in.readLine()) != null) {
            System.out.println("Server: " + fromServer);

            if (fromServer.equals("Bye."))
                break;

            fromUser = stdIn.readLine();
        if (fromUser != null) {
                System.out.println("Client: " + fromUser);
                out.println(fromUser);
        }
        }

        out.close();
        in.close();
        stdIn.close();
        kkSocket.close();
    }


}

UI

 import java.awt.event.ActionListener;



    public class KnockKnockWindow extends JFrame {

        JTextArea clientTextArea;
        JTextArea serverTextArea;
        JButton submitButton;


        public KnockKnockWindow() {

            super("Chat Window");
            setVisible(true);
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            setLocationRelativeTo(null);
            setSize(420,228);

            getContentPane().setLayout(null);

            clientTextArea = new JTextArea();
            clientTextArea.setBounds(10, 118, 278, 51);
            getContentPane().add(clientTextArea);


            serverTextArea = new JTextArea();
            serverTextArea.setBounds(10, 11, 278, 96);
            getContentPane().add(serverTextArea);

            submitButton = new JButton("Submit");
            submitButton.setBounds(298, 118, 89, 51);
            getContentPane().add(submitButton);
        }


        public void setServerText(String fromServer){
            serverTextArea.setText(fromServer);
        }

        public void setClientText(String fromClient){
            clientTextArea.setText(fromClient);
        }

        public String returnClientText(){
            return clientTextArea.getText();
        }

        public void addSubmitListener(ActionListener sub){
            submitButton.addActionListener(sub);
        }

    }   



The Controller


import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;


public class KnockKnockController {

    private KnockKnockClient client;
    private KnockKnockWindow window;

    public KnockKnockController(KnockKnockClient client, KnockKnockWindow window){
        this.client = client;
        this.window = window;

        window.addSubmitListener(new SubmitListener());
        window.setServerText(client.fromServer);
    }

    public class SubmitListener implements ActionListener{

        public void actionPerformed(ActionEvent arg0) {
            client.fromUser = window.returnClientText();
        }
    }
}

和主应用程序

import javax.swing.JFrame;

public class KnockTest extends JFrame{

    public static void main (String[] args){
        KnockKnockClient kkcl = new KnockKnockClient();
        KnockKnockWindow kkw = new KnockKnockWindow();
        KnockKnockController kkc = new KnockKnockController(kkcl,kkw);
    }
}

我们将首先运行服务器,然后是主应用程序。

但为什么我没有收到服务器发送的任何消息?当我点击开始时。服务器的文本区域应该显示 KnockKnock。但它似乎没有显示,有什么想法吗?抱歉,代码很长,但我不知道在这里缩短它们。因为我知道其中大部分都很重要

I am creating a simple Knock Knock application (socket programming) where there is a localhost server and there is a client.the program is simple, the server will tell the knock knock jokes, this is how it's supposed to go,

Server: Knock Knock
Client: Who's there?
Server: Turnip.
Client: Turnip Who?
Server: Turnip the heat.

So that's how the program supposed to go. but the thing is my GUI doesn't show any messages. on my Text area. Here are my codes.

The Server:

import java.net.*;
import java.io.*;

public class KnockKnockServer {
    public static void main(String[] args) throws IOException {

        ServerSocket serverSocket = null;
        try {
            serverSocket = new ServerSocket(4444);
        } catch (IOException e) {
            System.err.println("Could not listen on port: 4444.");
            System.exit(1);
        }

        Socket clientSocket = null;
        try {
            clientSocket = serverSocket.accept();
        } catch (IOException e) {
            System.err.println("Accept failed.");
            System.exit(1);
        }

        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
        BufferedReader in = new BufferedReader(
                new InputStreamReader(
                clientSocket.getInputStream()));
        String inputLine, outputLine;
        KnockKnockProtocol kkp = new KnockKnockProtocol();

        outputLine = kkp.processInput(null);
        out.println(outputLine);

        while ((inputLine = in.readLine()) != null) {
             outputLine = kkp.processInput(inputLine);
             out.println(outputLine);
             if (outputLine.equals("Bye."))
                break;
        }
        out.close();
        in.close();
        clientSocket.close();
        serverSocket.close();
    }
}

The KnockKnockProtocol

import java.net.*;
import java.io.*;

public class KnockKnockProtocol {
    private static final int WAITING = 0;
    private static final int SENTKNOCKKNOCK = 1;
    private static final int SENTCLUE = 2;
    private static final int ANOTHER = 3;

    private static final int NUMJOKES = 5;

    private int state = WAITING;
    private int currentJoke = 0;

    private String[] clues = { "Turnip", "Little Old Lady", "Atch", "Who", "Who" };
    private String[] answers = { "Turnip the heat, it's cold in here!",
                                 "I didn't know you could yodel!",
                                 "Bless you!",
                                 "Is there an owl in here?",
                                 "Is there an echo in here?" };

    public String processInput(String theInput) {
        String theOutput = null;

        if (state == WAITING) {
            theOutput = "Knock! Knock!";
            state = SENTKNOCKKNOCK;
        } else if (state == SENTKNOCKKNOCK) {
            if (theInput.equalsIgnoreCase("Who's there?")) {
                theOutput = clues[currentJoke];
                state = SENTCLUE;
            } else {
                theOutput = "You're supposed to say \"Who's there?\"! " +
                "Try again. Knock! Knock!";
            }
        } else if (state == SENTCLUE) {
            if (theInput.equalsIgnoreCase(clues[currentJoke] + " who?")) {
                theOutput = answers[currentJoke] + " Want another? (y/n)";
                state = ANOTHER;
            } else {
                theOutput = "You're supposed to say \"" + 
                clues[currentJoke] + 
                " who?\"" + 
                "! Try again. Knock! Knock!";
                state = SENTKNOCKKNOCK;
            }
        } else if (state == ANOTHER) {
            if (theInput.equalsIgnoreCase("y")) {
                theOutput = "Knock! Knock!";
                if (currentJoke == (NUMJOKES - 1))
                    currentJoke = 0;
                else
                    currentJoke++;
                state = SENTKNOCKKNOCK;
            } else {
                theOutput = "Bye.";
                state = WAITING;
            }
        }
        return theOutput;
    }
}

The Client.

import java.io.*;
import java.net.*;


public class KnockKnockClient {

    public String fromServer;
    public String fromUser;

    public void Client() throws IOException {

        Socket kkSocket = null;
        PrintWriter out = null;
        BufferedReader in = null;


        try {
            kkSocket = new Socket("127.0.0.1", 4444);
            out = new PrintWriter(kkSocket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream()));
        } catch (UnknownHostException e) {
            System.err.println("Don't know about host: 127.0.0.1");
            System.exit(1);
        } catch (IOException e) {
            System.err.println("Couldn't get I/O for the connection to: 127.0.0.1");
            System.exit(1);
        }

        BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));

        while ((fromServer = in.readLine()) != null) {
            System.out.println("Server: " + fromServer);

            if (fromServer.equals("Bye."))
                break;

            fromUser = stdIn.readLine();
        if (fromUser != null) {
                System.out.println("Client: " + fromUser);
                out.println(fromUser);
        }
        }

        out.close();
        in.close();
        stdIn.close();
        kkSocket.close();
    }


}

And The UI

 import java.awt.event.ActionListener;



    public class KnockKnockWindow extends JFrame {

        JTextArea clientTextArea;
        JTextArea serverTextArea;
        JButton submitButton;


        public KnockKnockWindow() {

            super("Chat Window");
            setVisible(true);
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            setLocationRelativeTo(null);
            setSize(420,228);

            getContentPane().setLayout(null);

            clientTextArea = new JTextArea();
            clientTextArea.setBounds(10, 118, 278, 51);
            getContentPane().add(clientTextArea);


            serverTextArea = new JTextArea();
            serverTextArea.setBounds(10, 11, 278, 96);
            getContentPane().add(serverTextArea);

            submitButton = new JButton("Submit");
            submitButton.setBounds(298, 118, 89, 51);
            getContentPane().add(submitButton);
        }


        public void setServerText(String fromServer){
            serverTextArea.setText(fromServer);
        }

        public void setClientText(String fromClient){
            clientTextArea.setText(fromClient);
        }

        public String returnClientText(){
            return clientTextArea.getText();
        }

        public void addSubmitListener(ActionListener sub){
            submitButton.addActionListener(sub);
        }

    }   



The Controller


import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;


public class KnockKnockController {

    private KnockKnockClient client;
    private KnockKnockWindow window;

    public KnockKnockController(KnockKnockClient client, KnockKnockWindow window){
        this.client = client;
        this.window = window;

        window.addSubmitListener(new SubmitListener());
        window.setServerText(client.fromServer);
    }

    public class SubmitListener implements ActionListener{

        public void actionPerformed(ActionEvent arg0) {
            client.fromUser = window.returnClientText();
        }
    }
}

And the Main Application

import javax.swing.JFrame;

public class KnockTest extends JFrame{

    public static void main (String[] args){
        KnockKnockClient kkcl = new KnockKnockClient();
        KnockKnockWindow kkw = new KnockKnockWindow();
        KnockKnockController kkc = new KnockKnockController(kkcl,kkw);
    }
}

We will run the server first, then the main.

But why is it that I am not receiving any messages from the server? when I click start. The text area of the Server should say KnockKnock. but it appears it is not showing, any idea? sorry for the long code post, but I do not know to shorten them here. since I know most of them are important

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

话少心凉 2025-01-11 14:24:04

正如您所说, while 循环只是获取文本并将其打印到控制台,您到底在哪里打印到文本区域。

// Put this code somewhere in the Client class so that when it receives something,
// it can be added to the `JTextArea`
while ((fromServer = in.readLine()) != null) 
{
    // You seems like missed the part that sends it to the textArea
    System.out.println("Server: " + fromServer);
    // Here send the received thing to your textarea, which goes something like this
    String str = "Server : " + fromServer + "\n";
    tarea.append(str);

    if (fromServer.equals("Bye."))
        break;

    // You can remove this part and put it inside the textField's actionPerformed method. 
    fromUser = stdIn.readLine();
    if (fromUser != null) 
    {
        System.out.println("Client: " + fromUser);
        out.println(fromUser);
    }
}

全新编辑:

只需从命令提示符启动 KnockKnockServer,而不是从扩展 JFrame 的类启动。只需简单地编写 java KnockKnockServer,即可在命令提示符下运行您的服务器,现在在新的命令提示符下编译我给您的这个类并像 java KnockKnockClient 一样运行它,您会发现它并没有完全工作。

import java.awt.BorderLayout;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import javax.swing.*;


public class KnockKnockClient extends JFrame
{

    public String fromServer;
    public String fromUser;
    // Added by me.--------------------
    private JTextArea tarea;
    private JTextField tfield;
    private JScrollPane spane;
    private PrintWriter out = null;
    /*------------------------------------*/

    public void Client() throws IOException 
    {
        Socket kkSocket = null;
        //PrintWriter out = null;  Shifted this to the instance variable
        BufferedReader in = null;

        BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
        try {
            kkSocket = new Socket("127.0.0.1", 4444);
            out = new PrintWriter(kkSocket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream()));
        } catch (UnknownHostException e) {
            System.err.println("Don't know about host: 127.0.0.1");
            System.exit(1);
        } catch (IOException e) {
            System.err.println("Couldn't get I/O for the connection to: 127.0.0.1");
            System.exit(1);
        }

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        JPanel contentPane = new JPanel();

        tarea = new JTextArea(10, 10);
        spane = new JScrollPane(tarea);
        tarea.setLineWrap(true);
        tfield = new JTextField(10);

        tfield.requestFocusInWindow();

        contentPane.setLayout(new BorderLayout());
        contentPane.add(spane, BorderLayout.CENTER);
        contentPane.add(tfield, BorderLayout.PAGE_END);

        setContentPane(contentPane);
        pack();
        setVisible(true); 

        Thread receiveMessage = new Thread(new ReceiveChat(in, stdIn, out));    
        receiveMessage.start();



        tfield.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                // Here you will send it to the server side too, put that code here
                fromUser = tfield.getText() + "\n";
                if (fromUser != null) 
                {
                    System.out.println("Client: " + fromUser);
                    tarea.append(fromUser);
                    out.println(fromUser);
                    tfield.setText("");
                }
            }
        });
        //out.close();
        //in.close();
        //stdIn.close();
        //kkSocket.close();
     }    

     private class ReceiveChat implements Runnable
     {
        private BufferedReader in;
        private BufferedReader stdIn;
        private PrintWriter out;

        public ReceiveChat(BufferedReader in, BufferedReader stdIn, PrintWriter out)
        {
            this.in = in;
            this.stdIn = stdIn;
            this.out = out;
        }

        public void run()
        {
            try
            {
                while ((fromServer = in.readLine()) != null) {
                //System.out.println("Server: " + fromServer);
                String str = "Server : " + fromServer + "\n";
                tarea.append(str);
                tarea.setCaretPosition(tarea.getDocument().getLength());

                if (fromServer.equals("Bye."))
                    break;
                /*Commented out by me.*/
                /*fromUser = stdIn.readLine();
                if (fromUser != null) {
                    System.out.println("Client: " + fromUser);
                    out.println(fromUser);
                }   */
                }
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
        }
     }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                KnockKnockClient client = new KnockKnockClient();
                try
                {
                    client.Client();
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                }
            }
        });
    }
}

只需让 KnockKnockServer 类的 while 循环如下所示:

while ((inputLine = in.readLine()) != null) 
{
    if (inputLine.length() > 0)
    {
        outputLine = kkp.processInput(inputLine);            
        out.println(outputLine);
        if (outputLine.equals("Bye."))
            break;
    }   
}

这将使其按预期工作。

Where exactly are you printing to the textarea as you are saying the while loop simply gets the text and prints it to the console.

// Put this code somewhere in the Client class so that when it receives something,
// it can be added to the `JTextArea`
while ((fromServer = in.readLine()) != null) 
{
    // You seems like missed the part that sends it to the textArea
    System.out.println("Server: " + fromServer);
    // Here send the received thing to your textarea, which goes something like this
    String str = "Server : " + fromServer + "\n";
    tarea.append(str);

    if (fromServer.equals("Bye."))
        break;

    // You can remove this part and put it inside the textField's actionPerformed method. 
    fromUser = stdIn.readLine();
    if (fromUser != null) 
    {
        System.out.println("Client: " + fromUser);
        out.println(fromUser);
    }
}

BRAND NEW EDIT :

Just start your KnockKnockServer from the command prompt, not from your class that extends JFrame. Just simply write java KnockKnockServer, to run your server on the command prompt, now on the new command prompt compile this class i am giving you and run it too like java KnockKnockClient, you will get an idea it's not working fully though.

import java.awt.BorderLayout;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import javax.swing.*;


public class KnockKnockClient extends JFrame
{

    public String fromServer;
    public String fromUser;
    // Added by me.--------------------
    private JTextArea tarea;
    private JTextField tfield;
    private JScrollPane spane;
    private PrintWriter out = null;
    /*------------------------------------*/

    public void Client() throws IOException 
    {
        Socket kkSocket = null;
        //PrintWriter out = null;  Shifted this to the instance variable
        BufferedReader in = null;

        BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
        try {
            kkSocket = new Socket("127.0.0.1", 4444);
            out = new PrintWriter(kkSocket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream()));
        } catch (UnknownHostException e) {
            System.err.println("Don't know about host: 127.0.0.1");
            System.exit(1);
        } catch (IOException e) {
            System.err.println("Couldn't get I/O for the connection to: 127.0.0.1");
            System.exit(1);
        }

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        JPanel contentPane = new JPanel();

        tarea = new JTextArea(10, 10);
        spane = new JScrollPane(tarea);
        tarea.setLineWrap(true);
        tfield = new JTextField(10);

        tfield.requestFocusInWindow();

        contentPane.setLayout(new BorderLayout());
        contentPane.add(spane, BorderLayout.CENTER);
        contentPane.add(tfield, BorderLayout.PAGE_END);

        setContentPane(contentPane);
        pack();
        setVisible(true); 

        Thread receiveMessage = new Thread(new ReceiveChat(in, stdIn, out));    
        receiveMessage.start();



        tfield.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                // Here you will send it to the server side too, put that code here
                fromUser = tfield.getText() + "\n";
                if (fromUser != null) 
                {
                    System.out.println("Client: " + fromUser);
                    tarea.append(fromUser);
                    out.println(fromUser);
                    tfield.setText("");
                }
            }
        });
        //out.close();
        //in.close();
        //stdIn.close();
        //kkSocket.close();
     }    

     private class ReceiveChat implements Runnable
     {
        private BufferedReader in;
        private BufferedReader stdIn;
        private PrintWriter out;

        public ReceiveChat(BufferedReader in, BufferedReader stdIn, PrintWriter out)
        {
            this.in = in;
            this.stdIn = stdIn;
            this.out = out;
        }

        public void run()
        {
            try
            {
                while ((fromServer = in.readLine()) != null) {
                //System.out.println("Server: " + fromServer);
                String str = "Server : " + fromServer + "\n";
                tarea.append(str);
                tarea.setCaretPosition(tarea.getDocument().getLength());

                if (fromServer.equals("Bye."))
                    break;
                /*Commented out by me.*/
                /*fromUser = stdIn.readLine();
                if (fromUser != null) {
                    System.out.println("Client: " + fromUser);
                    out.println(fromUser);
                }   */
                }
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
        }
     }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                KnockKnockClient client = new KnockKnockClient();
                try
                {
                    client.Client();
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                }
            }
        });
    }
}

Just let the while loop of your KnockKnockServer class look like this :

while ((inputLine = in.readLine()) != null) 
{
    if (inputLine.length() > 0)
    {
        outputLine = kkp.processInput(inputLine);            
        out.println(outputLine);
        if (outputLine.equals("Bye."))
            break;
    }   
}

This will make it work as expected.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文