我在2天前问了这个问题,但是我无法编辑(我不知道为什么)我也改变了我的课程的一部分。所以我已经检查了很多但是我真的不知道那个为什么它返回null值(在控制台上写道:Client says: null
),请帮帮我。
首先,我从文本区域获取文本,从客户端获取文本,然后我将其设置为我的文本区域,即输出(如Yahoo Messenger中的聊天框架),然后我将该文本发送到我的MainClient类。
我的聊天框架中执行的发送按钮操作:(我已经在聊天框架中测试了字符串文本,但它不是空的)
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
submit();
clear();
}
private void submit() {
String text = jTextArea1.getText();
jTextArea2.append(client.getCurrentName() + " : " + text + "\n");
MainClient.setText(client.getCurrentName() + " : " + text + "\n");
}
我的MainClient类:(其中一部分)
private static String text;
public static String getText() {
return text;
}
public static void setText(String text) {
MainClient.text = text;
}
static boolean closed = false;
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
String teXt = getText();
try {
os = new PrintWriter(c.getOutputStream(), true);
is = new BufferedReader(new InputStreamReader(c.getInputStream()));
} catch (IOException ex) {
Logger.getLogger(MainClient.class.getName()).log(Level.SEVERE, null, ex);
}
if (c != null && is != null && os != null) {
try {
os.println(teXt);//send data over socket.
String line = is.readLine();//recieve text from server.
System.out.println("Text received: " + line);
c.close();
} catch (IOException ex) {
System.err.println("read Failed");
}
}
}}
我的MainServer类:(其中一部分)
try {
BufferedReader streamIn = new BufferedReader(new InputStreamReader(client.getInputStream()));
boolean done = false;
String line =null;
while (!done ) {
line = streamIn.readLine();
if (line.equalsIgnoreCase("bye")) {
done = true;
} else {
System.out.println("Client says: " + line);
}
}
streamIn.close();
client.close();
server.close();
} catch (IOException e) {
System.out.println("IO Error in streams " + e);
}
}}
首先我将运行MainServer,然后运行MainClient(将显示聊天框架)。
编辑:请从这部分开始阅读:这是两个类,一个用于gui,另一个用于客户端。(网络)它在服务器的控制台上没有返回任何内容,因此它不会向客户端返回任何内容。帮帮我谢谢。我的GUI类:(其中一部分)(就像一个聊天框架,点击发送按钮。我会为服务器发送一些东西)
我的gui课程(聊天框架)的一部分:
private void SendActionPerformed(java.awt.event.ActionEvent evt) {
setButtonIsSelected(true);
submit();
clear();
}
private void submit() {
String text = jTextArea1.getText();
jTextArea2.append(client.getCurrentName() + " : " + text + "\n");
MainClient.setText(client.getCurrentName() + " : " + text + "\n");
}
private static boolean buttonIsSelected = false ;
public static boolean isButtonIsSelected() {
return buttonIsSelected;
}
public static void setButtonIsSelected(boolean buttonIsSelected) {
ChatFrame.buttonIsSelected = buttonIsSelected;
}
我的MainClient类:(其中一部分)
show a chat frame.
if ( ChatFrame.isButtonIsSelected() == true) {
String teXt = getText();
System.out.println(teXt);
os.println(teXt);
String line;
line = is.readLine();
System.out.println("Text received: " + line);
}
起初我将运行客户端类所以将运行gui类,其名称为chat Frame。
答案 0 :(得分:1)
似乎您的主要客户端正在连接到服务器并在启动时发送文本,而不是在有人输入内容时。所以变量文本为空。
当用户按下按钮并始终从服务器接收线路时,您应该通过线路发送文本。所以你应该专门设置一个线程(主线程没问题)从服务器读取而已。
当然,如果您使用主线程来接收服务器响应,则必须小心更新UI,因为您无法从任何线程执行此操作。在Swing中你必须调用一个特殊的方法(SwingUtilities#invokeLater,如果我记得很清楚),但在AWT我不知道。
希望它有所帮助。也许我毕竟没有得到正确的观点! :d
答案 1 :(得分:1)
尝试致电:
os.flush()
;
PrintWriter
上:
os.println(teXt);
答案 2 :(得分:0)
一个简单的解决方案可能是,将teXt变量发送到套接字时为空或空。请在os.println(teXt)调用之前插入一个System.out.println(teXt)进行双重检查,确实你已经向客户端发送了一些内容。
修改强>
最后,棘手的客户端/服务器部分正在按预期工作。我认为helios在他的评论中有正确的答案:当你用
之类的东西启动客户端时java -cp <your classpath> your.pckg.here.MainClient
它会立即调用getText()返回null,因为这是文本字段初始化的方式。因此,您将该空值分配给teXt,这就是您发送的内容。
此代码不会对您在聊天框架中执行或更改的任何内容作出反应。
因此解决方案是重新设计应用程序中的流程,以便当且仅当在聊天框架上按下按钮时,客户端才真正发送内容。
修改强>
这是一个非常简单但有效的带有GUI的客户端/服务器系统示例。代码非常糟糕(错误的异常处理,客户端和服务器不会终止,必须被“杀死”,丑陋的GUI),但它展示了基础知识。
服务器:
public class Server {
public static void main(String[] args) throws Exception {
ServerSocket socket = new ServerSocket(12345);
while(true) {
Socket client = socket.accept();
InputStream in = client.getInputStream();
int i = in.read();
while (i != -1) {
System.out.print((char) i);
i = in.read();
}
System.out.println();
in.close();
}
}
}
服务器侦听端口12345,只是将所有传入的字节作为字符转储到控制台。它将永远这样做(真正的服务器可以停止......)
GUI:
public class GUI extends JFrame {
public GUI() {
setSize(100, 100);
Container contentPane = getContentPane();
Button button = new Button("Press me");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Client.send("Button pressed");
}
});
contentPane.add(button);
}
}
除了显示单个按钮的无标题框架外,别无其他。如果按此按钮,它将向Client类发送一条文本消息(iaw - 使用静态文本调用Client.send方法)
客户:
public class Client {
public static void main(String[] args) throws Exception {
GUI gui = new GUI();
gui.setVisible(true);
}
public static void send(String msg) {
try {
Socket socket = new Socket("localhost", 12345);
OutputStream out = socket.getOutputStream();
out.write("Hello world".getBytes());
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
客户端创建并生成华丽的GUI。它包含发送服务。根据请求(调用send方法),它将建立与服务器的连接并将字符串作为字节发送。
所以重点是:为了发送一些东西,你必须告诉客户这样做。在您的代码上也是如此:只在客户端类上设置字段不会触发发送例程。实现一个send方法,并在有东西发送时调用它。
(我没有在示例中包含packagenames和import,但我只使用了标准的java(swing)类。)