为啥它返回一个空值?!!(客户端/服务器应用程序)

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 并停止助长这种不良行为。

以上是关于为啥它返回一个空值?!!(客户端/服务器应用程序)的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的数据表单元格返回空值?

为啥 eloquent orm 上的查询语句结果返回空值

为啥当 == 为空值返回 true 时 >= 返回 false?

为啥在返回值之前将字符串与空值连接?

为啥针对 S3 的 pyspark sql 查询返回空值

为啥 DataContext 为 ListView 项目之外的项目返回空值?