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

时间:2010-01-15 16:49:31

标签: java networking

我在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。

3 个答案:

答案 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)类。)