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

发布于 2024-08-18 12:30:17 字数 3603 浏览 5 评论 0原文

我两天前问过这个问题,但我无法编辑它(我不知道为什么)我也改变了我的课程的某些部分。我也检查了很多,但我真的不知道为什么它会返回null 值(在控制台上写的是:客户端说: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);

}

首先我将运行客户端类,因此将运行名为chat Frame的gui类。

i have asked this question 2 days before but I can not edit that(I don't know why)also i have changed some part of my classes.also I have checked it a lot but really I don't know that why it returns null value(on the console is written :Client says: null
),please help me.

at first i get the text from a text area which get text from client and then i will set it to my text area which is the output(like chat frame in Yahoo Messenger) and then i will send that text to my MainClient class.

my send button action performed in my chat frame:(I have tested the String text in the chat frame and it wasn't null)

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");
}

my MainClient class:(a part of that)

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");
       }
    }
}}

my MainServer class:(a part of that)

    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);
    }
}}

At first I will run the MainServer and then I will run the MainClient(which will show the chat frame).

EDIT:please start reading from this part: these are two classes ,one for gui and the other for client.(network) it returns nothing on the console for server so it will return nothing to the client.please help me thanks. my GUI class:(a part of that) (like a chat frame which by clicking on the Send button .I will send something for the server)

my gui class(chat frame) a part of that:

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;
}

my MainClient class:(a part of that)

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);

}

at first I will run the client class So the gui class will be run which name is chat Frame.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

话少情深 2024-08-25 12:30:17

看来您的主客户端正在连接到服务器并在启动时立即发送文本,而不是在有人输入内容时发送文本。所以变量文本为空。

当用户按下按钮时,您应该通过线路发送文本,并始终从服务器接收线路。所以你应该专门一个线程(主线程可以)从服务器读取数据,仅此而已。

当然,如果您使用主线程接收服务器响应,则必须小心更新 UI,因为您无法从任何线程执行此操作。在 Swing 中你必须调用一个特殊的方法(SwingUtilities#invokeLater 如果我没记错的话),但在 AWT 中我不知道。

希望有帮助。也许我根本没有得到正确的观点! :D

It seems your main client is connecting to the server and sending text right on startup, not when someone enters something. So variable text is null.

You should send text over the wire when the user presses the button and receive lines from server always. So you should dedicate a thread (the main thread is ok) to read from server and nothing more.

Of course, if you use the main thread to receive server responses you have to be careful to update your UI because you cannot do it from any thread. In Swing you have to call a special method (SwingUtilities#invokeLater if I remember well) but in AWT I don't know.

Hope it helps. Maybe I'm not getting the correct point after all! :D

最近可好 2024-08-25 12:30:17

尝试调用:

os.flush();

调用后立即在您的 PrintWriter 上:

os.println(teXt);

Try calling:

os.flush();

on your PrintWriter immediately after calling:

os.println(teXt);

青巷忧颜 2024-08-25 12:30:17

一个简单的解决方案可能是,当您将 teXt 变量发送到套接字时,它为 null 或为空。请在 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 方法)

Client:

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

A trivial solution could be, that your teXt variable is null or empty at the time you send it to the socket. Please insert a System.out.println(teXt) right before your os.println(teXt) call to double check, that you really send something to the client.

Edit

So at last the tricky client/server part is working as it should. I think helios has the right answer in his comments: When you start the client with something like

java -cp <your classpath> your.pckg.here.MainClient

it will immediatly call getText() which returns null because that's how the text field gets initialized. So you assign that null value to teXt and that's what you send.

This code does not react on anything you do or change in the chat frame.

So the solution is to redesign the flow in the application so that the client really sends something if and only if a button is pressed on the chat frame.

Edit

This is a very simple but working example of a client/server system with a GUI. The code is extremely bad (bad exception handling, client and server won't terminate and have to be 'killed', ugly GUI) but it demonstrates the basics.

Server:

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();
        }
    }

}

The server listens on port 12345 and simply dumps all incoming bytes as characters to the console. It will do this forever (real server can be stopped...)

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);
    }

}

Nothing but a titleless frame showing a single button. If you press this button, it will send a text message to the Client class (iaw - call the Client.send method with a static text)

The Client:

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();
        }
    }

}

The client creates and spawnd the gorgeous GUI. And it contains the send service. Upon request (calling send method) it will establish a connection to the server and send the String as bytes.

So the point is: in order to send something, you have to tell the client to do so. And that's the same on your code: just setting a field on the client class will not trigger the send routine. Implement a send method and call it whenever you have something to send.

(I didn't include packagenames and imports in the examples, but I only used standard java (swing) classes.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文