为啥它返回一个空值?!!(客户端/服务器应用程序)
Posted
技术标签:
【中文标题】为啥它返回一个空值?!!(客户端/服务器应用程序)【英文标题】:Why does it return a null value?!!(client/server application)为什么它返回一个空值?!!(客户端/服务器应用程序) 【发布时间】:2011-01-05 14:35:15 【问题描述】:我在 2 天前问过这个问题,但我无法编辑它(我不知道为什么)我也改变了我的部分课程。我也检查了很多,但我真的不知道为什么它返回空值(控制台上写着: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 类。
【问题讨论】:
这些是非常简单的代码,但是我发送它是因为我没有发布的代码的另一部分可能会出错,我只是让我的朋友们更容易获得整个代码! 是的,我的观点是,您应该尽最大努力找出问题所在,而不是仅仅将一堆代码放入一个问题中并要求我们找出问题所在。 我在遵循您的流程时遇到问题,当您的 MainClient.main 方法运行时(程序启动时),它首先获取 teXt 变量(此时为空),然后实例化我猜想 MainFrame 的一个对象包含您的 jTextArea1,然后继续通过套接字将内容发送到 teXt(它仍然是一个空字符串)?您的 MainFrame 从未与 MainClient 进行过交互。 【参考方案1】:您的主客户端似乎正在连接到服务器并在启动时发送文本,而不是在有人输入内容时。所以可变文本为空。
当用户按下按钮并始终从服务器接收线路时,您应该通过线路发送文本。所以你应该专门一个线程(主线程没问题)从服务器读取,仅此而已。
当然,如果您使用主线程接收服务器响应,则必须小心更新 UI,因为您无法从任何线程执行此操作。在 Swing 中你必须调用一个特殊的方法(如果我没记错的话是 SwingUtilities#invokeLater),但在 AWT 中我不知道。
希望对您有所帮助。也许我毕竟没有得到正确的观点! :D
【讨论】:
ahan,我在 MainClient 中更改了这一行:if (c != null && is != null && os != null) 与 if (c != null && is != null && os != null && teXt !=null) 但它什么也不返回。(也不返回 null) 或者我错过了一些东西,或者你错过了一些东西(关于它是如何工作的)。我要说的是:您的 MAIN 方法,当您运行客户端程序时开始连接到服务器并立即发送 MainClient.text 字段中的任何内容。在几毫秒内。因此,您无需更改输入一些文本,单击您的按钮并填充变量。当你点击按钮时,你必须让你的“向服务器发送文本”运行。所以不要放入main方法!!! 在您的音乐系统中思考。就像它想在您按下电源按钮时立即播放 CD,而不是在插入 CD 并按播放时播放。 我已经尝试过你所说的,我在聊天框中调用了 MainClient 的另一个方法(从客户端获取文本并将其发送到服务器),当客户端单击发送按钮时,但突然我的框架会挂起(就像我点击发送按钮时什么都不会发生!) 嗨,我已经编辑了我的帖子。但现在它什么也没有返回。你能帮我吗?谢谢【参考方案2】:尝试调用:
os.flush()
;
致电后立即在您的PrintWriter
上:
os.println(teXt);
【讨论】:
【参考方案3】:一个简单的解决方案可能是,您的 teXt 变量在您将其发送到套接字时为空或为空。请在您的 os.println(teXt) 调用之前插入一个 System.out.println(teXt) 以仔细检查您是否真的向客户端发送了一些东西。
编辑
因此,棘手的客户端/服务器部分终于可以正常工作了。我认为 helios 在他的 cmets 中有正确的答案:当你用类似的东西启动客户端时
java -cp <your classpath> your.pckg.here.MainClient
它将立即调用返回 null 的 getText(),因为这就是文本字段的初始化方式。因此,您将该空值分配给 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 并将所有传入字节作为字符转储到控制台。它将永远这样做(可以停止真正的服务器......)
图形界面:
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 方法),它将建立与服务器的连接并将字符串作为字节发送。
所以重点是:为了发送一些东西,你必须告诉客户这样做。您的代码也是如此:仅在客户端类上设置一个字段不会触发发送例程。实现一个发送方法,并在您有东西要发送时调用它。
(我没有在示例中包含包名和导入,但我只使用了标准的 java (swing) 类。)
【讨论】:
把 os.println(teXt) 换成 os.println("Hello Server") 能用吗? 我明白你的意思,但是在我的客户端应用程序中,我有两个不同的包,一个用于 gui,另一个用于网络,我现在该怎么办,真的很困惑。 嗨,我已经编辑了我的帖子。但现在它什么也没有返回。你能帮我吗?谢谢 @Andreas_D:请阅读:slash7.com/2006/12/22/vampires 并停止助长这种不良行为。以上是关于为啥它返回一个空值?!!(客户端/服务器应用程序)的主要内容,如果未能解决你的问题,请参考以下文章