使用服务器和UI敲击Knock应用程序

我正在创建一个简单的Knock Knock应用程序(套接字编程),其中有一个localhost服务器,并且有一个客户端。程序很简单,服务器会告诉敲敲笑话,这是它应该如何去,

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。 但它似乎没有显示,任何想法? 对不起长码贴,但我不知道在这里缩短它们。 因为我知道他们中的大多数都很重要

您正在打印到textarea的确切位置,因为您说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; } } 

这将使其按预期工作。