我正在创建一个简单的Knock Knock应用程序(套接字编程),其中有一个localhost服务器,并且有一个客户端。该程序很简单,服务器将告诉敲敲笑话,这是它应该如何去,< / p>
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。但它似乎没有显示,任何想法?对不起,长代码帖,但我不知道在这里缩短它们。因为我知道他们中的大多数都很重要
答案 0 :(得分:5)
你正在打印到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;
}
}
这将使其按预期工作。