3

我实际上正在尝试创建一个程序:

public void setUpNetwork(){
    try {
            Socket sock = new Socket("localhost", 1101);
            InputStreamReader read = new InputStreamReader(sock.getInputStream());
            buff = new BufferedReader(read);
            write = new PrintWriter(sock.getOutputStream());
            System.out.println("Network Established");
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        }
}

在这里,一旦建立了套接字连接,我就会尝试将用户输入的数据传递给打印流,然后在控制台中打印出数据。

我的服务器类只有这么多:

        ServerSocket server = new ServerSocket(1101);
        Socket socket = server.accept();

当我运行它时(在运行时,我首先运行服务器,然后运行 ​​ChatSetUp 类),控制台上没有打印任何内容!是否因为 sersock.accept() 提供了一个具有不同端口的套​​接字连接,并且客户端无法与服务器通信?如果是这样,我需要将套接字对象从服务器传递到不同类中的 setUpNetwork(),以便我可以在其上创建输入流。我该怎么做?

编辑:

我对整个程序进行了更多修改!我正在使用 Swing 创建 GUI,其中当用户在文本字段中输入文本并点击发送时,它会触发侦听器,这就是我将文本添加到 PrintWriter 的地方。整个代码如下: ....和 ​​setUpNetwork() 也是这个类的一部分(不包括在下面)

编辑:在同一程序中包含服务器代码并为服务器启动一个新线程。

public class ChatGraphs {

JTextField field;
JTextArea area;
PrintWriter write;
BufferedReader buff;
Socket sock;

public static void main(String[] args) {
    ChatGraphs grap = new ChatGraphs();
    grap.doIt();
}

private void doIt() {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


    JPanel allPanel = new JPanel();
    allPanel.setLayout(new BoxLayout(allPanel, BoxLayout.Y_AXIS));

    JPanel areaPanel = new JPanel();
    areaPanel.setLayout(new FlowLayout());
    JLabel alabel = new JLabel("Chats");
    area = new JTextArea(20, 50);
    area.setEditable(false);
    areaPanel.add(alabel);
    areaPanel.add(area);

    JPanel textPanel = new JPanel();
    textPanel.setLayout(new FlowLayout());
    JLabel flabel = new JLabel("Enter");
    field = new JTextField(20);
    JButton button = new JButton("Send");
    button.addActionListener(new ButtonListen());
    textPanel.add(flabel);
    textPanel.add(field);
    textPanel.add(button);

    allPanel.add(areaPanel);
    allPanel.add(textPanel);

    ConnectServer con = new ConnectServer();
    Thread t = new Thread(con);
    t.start();

    AddData add = new AddData();
    Thread t1 = new Thread(add);
    t1.start();

    //setUpServer();
    setUpClient();

    frame.setSize(700,500);
    frame.setVisible(true);
    frame.getContentPane().add(allPanel);
}

public class ButtonListen implements ActionListener{

    @Override
    public void actionPerformed(ActionEvent arg0) {     
        write.println(field.getText());
        write.flush();
        field.setText("");
        field.setRequestFocusEnabled(true);

    }
}

private void setUpClient(){
    try {
        sock = new Socket("localhost", 1101);
        InputStreamReader read = new InputStreamReader(sock.getInputStream());
        buff = new BufferedReader(read);
        System.out.println("Network Established");
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public class AddData implements Runnable{

    @Override
    public void run() {
        String line="";
        try {
            while((line=buff.readLine())!=null){
                System.out.println("Another net");
                area.append(line);
            }
            buff.close();
            write.close();
            sock.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

public class ConnectServer implements Runnable{

    public void run() {
        ServerSocket sersock = null;
        Socket sock = null;
        try {
                sersock = new ServerSocket(1101);
                sock = sersock.accept();
                write = new PrintWriter(sock.getOutputStream());
                sersock.close();
                sock.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    }

}

我得到的例外是:

Exception in thread "Thread-2" java.lang.NullPointerException
    at org.sockets.ChatGraphs$AddData.run(ChatGraphs.java:120) // This line is : while((line=buff.readLine())!=null)
    at java.lang.Thread.run(Unknown Source)
Network Established
4

2 回答 2

4

PrintWriter是那些在缓冲和刷新方面表现不佳的类之一。一个简单的解决方法是使用

new PrintWriter(sock.getOutputStream(), true);

启用自动刷新。

或者您可以在write.flush()每次将数据发送到客户端时调用。

请注意,您需要flush()在关闭之前调用一次,PrintWriter因为它本身不会这样做(与任何其他 I/O 类不同)。

于 2013-10-01T10:17:06.470 回答
3

客户端和服务器如何通过 Sockets 找到对方?

  • 客户端需要知道服务器的网络地址(IP-Address)和服务器正在监听的端口号。
  • 服务器只需要知道它正在监听哪个端口。如果它有更多具有不同 IP 地址的网络接口,您可以选择限制服务器侦听其中一个网络接口(一个 IP 地址)

所以将客户端连接到服务器的代码片段如下:

Socket socket4Client = new Socket("IP-Address, e.g. 123.45.67.89", PORT_NUMBER);

服务器的代码片段如下所示:

ServerSocket serverSocket = new ServerSocket(PORT_NUMBER);
Socket socket4Server = serverSocket.accept(); // Waits for a Client to connect

对于服务器端,您很可能希望为每个传入连接启动一个新线程。检查这些Tiny Applications以获得一些非常简单(只是没有过度简化)的示例。

编辑/添加:

关于上NullPointerException线的新问题while(..

你得到了异常,因为buff它是空的。发生这种情况是因为线程ConnectServer是在调用方法之前启动的setUpClient()。您可以创建线程,但必须setUpClient()在实际start()线程之前调用。

于 2013-10-07T11:52:00.097 回答