Java网络示例?

时间:2014-08-24 23:59:41

标签: java networking network-programming

我现在开始在Daniel Liang的“Java编程简介”一书的帮助下学习Java网络API。出现的一个例子如下。这个想法是有一个服务器和一个客户端。客户端向服务器提交半径值,该服务器从中计算圆的一个区域并将其发送回客户端。但是,下面的代码(我仔细检查过)不起作用。

Client.java

import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Client extends JFrame {
    private JTextField jtf = new JTextField();
    private JTextArea jta = new JTextArea();
    private DataOutputStream toServer;
    private DataInputStream fromServer;

    public static void main(String[] args) {
        new Client();
    }   

    public Client()
    {
        //GUI
        JPanel p = new JPanel();
        p.setLayout(new BorderLayout());
        p.add(new JLabel("Enter Radius"), BorderLayout.WEST);
        p.add(jtf, BorderLayout.CENTER);
        jtf.setHorizontalAlignment(JTextField.RIGHT);

        setLayout(new BorderLayout());
        add(p, BorderLayout.NORTH);
        add(new JScrollPane(jta), BorderLayout.CENTER);

        jtf.addActionListener(new TextFieldListener());

        setTitle("Client");
        setSize(500,300);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);

        try {
            Socket socket = new Socket("ip address of computer running server window", 8000);
            fromServer = new DataInputStream(socket.getInputStream());
            toServer = new DataOutputStream(socket.getOutputStream());
        }
        catch(IOException ex){
            jta.append(ex.toString() + "\n");
        }
    }
    private class TextFieldListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            try {
                double radius = Double.parseDouble(jta.getText().trim());
                toServer.writeDouble(radius);
                toServer.flush();

                double area = fromServer.readDouble();

                jta.append("Radius is " + radius + "\n");
                jta.append("The Area recieved from the server is " + area + "\n");
            }
            catch(IOException ex){
                System.err.println(ex);
            }
        }
    }
}

Server.java

import java.io.*;
import java.net.*;
import java.util.*;
import java.awt.*;
import javax.swing.*;

public class Server extends JFrame {

    private JTextArea jta = new JTextArea();

    public static void main(String[] args) {
        new Server();
    }
    public Server()
    {
        //GUI
        setLayout(new BorderLayout());
        add(new JScrollPane(jta), BorderLayout.CENTER);

        setTitle("Server");
        setSize(500,300);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);

        //Server Code
        try {
            ServerSocket serverSocket = new ServerSocket(8000);//Establish this server with the port 8000
            jta.append("Server started at " + new Date() + "\n");

            //Allows server to listen for connections
            Socket socket = serverSocket.accept();

            //Data streams for writing/reading data into the connected socket from above
            DataInputStream inputFromClient = new DataInputStream(socket.getInputStream());
            DataOutputStream outputToClient = new DataOutputStream(socket.getOutputStream());


            while(true) {
                double radius = inputFromClient.readDouble();
                double area = radius * radius * Math.PI;

                outputToClient.writeDouble(area);

                jta.append("Radius recieved from client: " + radius + "\n");
                jta.append("Area found: " + area + "\n");
            }
        }
        catch(IOException ex){
            System.err.println(ex);
        }
    }
}

但是,当我运行此代码并输入半径值时,我从客户端窗口收到以下错误消息:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at Client$TextFieldListener.actionPerformed(Client.java:51)
    at javax.swing.JTextField.fireActionPerformed(JTextField.java:492)
    at javax.swing.JTextField.postActionEvent(JTextField.java:705)
    at javax.swing.JTextField$NotifyAction.actionPerformed(JTextField.java:820)
    at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1645)
    at javax.swing.JComponent.processKeyBinding(JComponent.java:2859)
    at javax.swing.JComponent.processKeyBindings(JComponent.java:2894)
    at javax.swing.JComponent.processKeyEvent(JComponent.java:2822)
    at java.awt.Component.processEvent(Component.java:6191)
    at java.awt.Container.processEvent(Container.java:2084)
    at java.awt.Component.dispatchEventImpl(Component.java:4776)
    at java.awt.Container.dispatchEventImpl(Container.java:2142)
    at java.awt.Component.dispatchEvent(Component.java:4604)
    at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1856)
    at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:722)
    at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1000)
    at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:865)
    at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:686)
    at java.awt.Component.dispatchEventImpl(Component.java:4648)
    at java.awt.Container.dispatchEventImpl(Container.java:2142)
    at java.awt.Window.dispatchEventImpl(Window.java:2492)
    at java.awt.Component.dispatchEvent(Component.java:4604)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:717)
    at java.awt.EventQueue.access$400(EventQueue.java:82)
    at java.awt.EventQueue$2.run(EventQueue.java:676)
    at java.awt.EventQueue$2.run(EventQueue.java:674)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:86)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:690)
    at java.awt.EventQueue$3.run(EventQueue.java:688)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:86)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:687)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

我该如何解决这个问题? 这是我从中得到的书的pdf链接。检查第33章,第1180页(pdf第1213页): http://ccis141.files.wordpress.com/2013/09/introduction-to-java-programming-comprehensive-9th-edition.pdf

2 个答案:

答案 0 :(得分:2)

变量toServernull

在构造函数中初始化它时,JFrame在初始化toServer之前对用户可见。可能发生的情况是Client实例无法建立与服务器的连接,并且new Socket("ip address of computer running server window", 8000)被阻止,并最终会超时。 但是,UI已在运行,用户可以已经触发请求。

当与服务器的连接成功时,NPE不会发生,一切正常。

一个简单的测试就是移动线

setVisible(true);

toServer初始化之后,在这种情况下,只有在连接成功且toServer不为空时才会显示客户端UI。

答案 1 :(得分:0)

就网络代码而言,我在这里看不出任何错误。与上述用户之一一样,实际情况是您的客户端由于某种原因未建立与您的服务器的连接,但仍允许用户提交请求。我怀疑它与你的TextFieldListener有关。既然您提到这是您第一次使用Java学习网络,我建议您在没有花哨的GUI的情况下启动并使用命令行应用程序。通过这种方式,您可以更多地关注网络方面,而不必处理UI和事件处理(稍后您可以使它变得漂亮)。为此,我写了一个客户端的非GUI形式,它仍然可以与你现有的服务器一起使用(没有错)。

import java.net.*;
import java.io.*;
import java.util.*;

public class ConsoleClient {

    Socket connectionSocket;
    DataInputStream inputStream;
    DataOutputStream outputStream;
    Scanner input;
    double radius;

    public static void main(String[] args) {
        new ConsoleClient();

    }
    public ConsoleClient()
    {
        input = new Scanner(System.in); 
        try 
        {
            connectionSocket = new Socket("Server IP", 8000);
            inputStream = new DataInputStream(connectionSocket.getInputStream());
            outputStream = new DataOutputStream(connectionSocket.getOutputStream());

            System.out.println("Connection established !");

            System.out.println("Please enter a radius: ");
            radius = input.nextDouble();

            outputStream.writeDouble(radius);
            outputStream.flush();

            System.out.println("Data from Client send !");

            System.out.println("The area received is " + inputStream.readDouble());

        }
        catch(Exception ex)
        {
            System.out.println(ex + "");
        }

    }
}