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は、バッファリングとフラッシュに関してうまく動作しないクラスの 1 つです。簡単な修正は使用することです

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

自動フラッシュを有効にします。

または、write.flush()データをクライアントに送信する必要があるたびに呼び出すことができます。

flush()を閉じる前に 1 回呼び出す必要があることに注意してくださいPrintWriter(他の I/O クラスとは異なり)。

于 2013-10-01T10:17:06.470 に答える
3

クライアントとサーバーはソケットを介してどのようにお互いを見つけるのですか?

  • クライアントは、サーバーのネットワーク アドレス (IP アドレス) と、サーバーがリッスンしているポート番号を知る必要があります。
  • サーバーは、リッスンしているポートを知る必要があるだけです。異なる IP アドレスを持つ複数のネットワーク インターフェイスがある場合は、必要に応じて、ネットワーク インターフェイスの 1 つ (1 つの 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(..

buffnull であるため、例外が発生します。ConnectServerこれは、メソッドsetUpClient()が呼び出される前にスレッドが開始されるために発生します。setUpClient()スレッドを作成できますが、実際にスレッドを作成する前に呼び出す必要がありstart()ます。

于 2013-10-07T11:52:00.097 に答える