【问题标题】:Why does the server not write to the client? [duplicate]为什么服务器不写入客户端? [复制]
【发布时间】:2016-05-09 04:04:04
【问题描述】:

这是我的服务器类,它打开一个服务器套接字以从一个客户端获取信息,然后使用用户类将字符串发送给数组中的所有用户:

public class Server  {
    static ServerSocket server;
    static Socket client;
    static DataOutputStream out;
    static DataInputStream in;
    static int port = 7767;
    static Users[]User = new Users[10];

public static void main(String[] args)throws Exception{
    try {
        System.out.print("starting");
        server = new ServerSocket(port);
        while((client = server.accept() )!= null ){

             for(int i=0; i<10; i++){
                // System.out.println("input connection");
                 out= new DataOutputStream(client.getOutputStream());
                 in = new DataInputStream(client.getInputStream());
                if(User[i] == null)
                {
                    User[i] = new Users(out, in, User);
                    Thread thread = new Thread(User[i]);
                    thread.start();

                }
             }
        }

             } catch (IOException e) {

                e.printStackTrace();


}

这个用户类只保存谁是客户端的信息,然后向所有用户发送服务器发送的字符串,我曾经为message = in.readUTF(); 获得 NullPointException,但现在,什么都没有发生。

public class Users implements Runnable {
DataOutputStream out;
DataInputStream in;
Users[] User = new Users[10];
public Users(DataOutputStream out, DataInputStream in, Users[] User)
{
    this.in = in;
    this.out = out;
    this.User = User;

}
public void run(){
    while(true){
        try{
            BufferedReader bri = new BufferedReader(new InputStreamReader(in));

        String  message;
        message = bri.readLine();

            for(int i=0; i<10; i++){
                if(User[i] != null)
            {
                    BufferedWriter br = new BufferedWriter(new OutputStreamWriter(out));
                User[i].br.write(message + "\n");
                }

            }

        }
        catch(IOException e){
    // catching and doing something about it and stuff
        }

}
}`

客户:(减去所有摆动的东西以节省问题空间)

public class Client implements WriteGui {
static Socket client;
static DataInputStream in;
static DataOutputStream out;
JTextArea msgout;
private JFrame frame;
private JTextField msgA;
private JTextField nameA;



/**
 * Create the application.
 */
public Client() {
    initialize();
    CStart();
}`

    public void actionPerformed(ActionEvent arg0) {
            if(nameA.getText() == ""){
             nameA.setText(getname());


            }
            String message;

            message = (nameA.getText()+": "+ msgA.getText());

        try {
                BufferedWriter br = new BufferedWriter(new OutputStreamWriter(out));
                br.write(message+"\n");


            } catch (IOException e) {
            msgout.append("error!");

            }


        }
public void write(String s) {
    msgout.append(s+ "/n" );

}
private String getname(){
    return JOptionPane.showInputDialog(frame,"fill out name" , "name", JOptionPane.QUESTION_MESSAGE);



}
public void CStart(){
 int port = 7767;
    String host = "localhost";
    try {

    client = new Socket(host, port);
    msgout.append("starting");
     in = new DataInputStream(client.getInputStream());
  out = new DataOutputStream(client.getOutputStream());
  Input input = new Input(in, this);
  Thread thread = new Thread(input);
  thread.start();

    }

    catch(Exception e) {
        msgout.append("error");
    }

我还有一个简短的输入类,可以将消息输入到客户端:

public class Input implements Runnable  {
WriteGui gui;
DataInputStream in; 
static BufferedReader br;
public Input(DataInputStream in, WriteGui gui){
    this.in = in;
    this.gui = gui;

}

public void run() {
    String message;
br = new BufferedReader(new InputStreamReader(in));
try {
    message = br.readLine();
    gui.write(message);
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

就像我说的,我将错误追溯到 Users 类,但不能保证每次都会发生 NullPointerException。尽管它应该使用更多资源,但它似乎仍然在服务器/用户代码中。 谁能帮我弄清楚为什么这个 Datainputstream 似乎不起作用?

编辑:它停止产生 NullPointerException,现在在几次尝试而不是消息后按开始后,它发送一个盒子形状。因此,UTF 读取似乎确实存在问题。即使将 OutputStreamWriter 更改为 DataInputStream,它也不起作用。

【问题讨论】:

  • 我认为问题在于您正在使用OutputStreamWriter 写入数据,而您正在尝试使用DataInputStream 读取它。尝试使用相同类型的流来写入/读取数据。
  • 我尝试只使用 DataInputStream 但它不起作用,这就是为什么我查找它并且有人建议使用 OutputStreamWriter 来解决类似问题
  • 我在没有静态引用的情况下尝试过,所以这不是资源管理问题或我的整体问题的原因。我在这里的代码中保留了静态只是为了使示例更整洁,因为它似乎不会影响问题。

标签: java sockets tcp datainputstream


【解决方案1】:

为了使readUTF() 方法起作用,数据必须以特定方式格式化,而使用OutputStreamWriter 编写数据时并非如此。

我建议您使用BufferedReaderBufferedWriter,使用write(string+"\n") 写一些东西,使用readLine() 阅读。为了使它起作用,您必须在每条消息的末尾添加一个新行 \n

这是一个例子:

try(BufferedWriter bw = new BufferedWritter(new OutputStreamWriter(socker.getOutputStream()))){
    bw.write(message + "\n");
}catch(IOException e){
    e.printStackTrace();
}


try(BufferedReader br = new BufferedReader(new InputStreamReader(socker.getInputStream()))){
    String message = br.readLine();
}catch(IOException e){
    e.printStackTrace();
}

【讨论】:

  • 您是否建议在流的两侧都这样做?
  • @Alexandre 是的,您应该使用与作者相同类型的阅读器。如果您逐行读取数据(使用readLine()),请确保使用换行符“\n”终止您的消息。
  • 这很奇怪。我刚刚使用此建议对其进行了几次测试,但没有帮助。我得到的盒子和其他奇怪的符号已经消失了,但发送的消息没有出现。
  • @Alexandre 您能否更新您的问题以反映您所做的更改?
  • 我更新了这个以匹配我为符合您的理论所做的更改。这对我来说是一个奇怪的问题。
【解决方案2】:

由于您现在使用的是BufferedWriter,因此您需要在适当的时间使用flush()它,即当您从写作切换到阅读时。

【讨论】:

  • 好的。您能否提供一个示例或将我指向其他地方的示例?因为我假设我需要对其进行同步或计时,就好像我只是在从服务器获取输出流之前刷新编写器一样?
  • 您不需要一行代码的示例。不要制造想象中的问题。在你阅读之前冲洗它。这并不难。我无法理解“因为”之后的部分。
  • 如果我在将消息发送到服务器后使用刷新运行代码,我会再次收到 NullPointerException,如果在我发送回消息后立即刷新流,我也会收到异常错误给客户。
  • 我真的希望任何计算机程序员都能在没有NullPointerExceptions 的情况下编写代码;在解决不同的问题时不要吹嘘它们;并且在描述任何需要解决方案的问题时,要足够详细地描述,以便实际提供解决方案。您的问题现在是一个记录不足的重复项。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-29
  • 2017-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-04
  • 1970-01-01
相关资源
最近更新 更多