1

私はプログラミングが初めてで、この小さなハードルについて助けが必要です。サーバーとチャットクライアントを使用して、簡単なチャットプログラムを作成しています。したがって、クライアントが起動し、ネットワーク接続を正常に作成します。これにはPrintWriter、サーバーに送信する が含まれます。次に、別のクラス ( my ActionListener) で writer 変数を呼び出すと、 . で void になりますNullPointerException

そのため、ActionListener が実行されるたびに setupnetworking を呼び出してみましたが、最終的に多くの接続が発生し、メッセージが複数回出力されます。メソッドでsetupnetworking を保持し、クラスmain()の変数値を保持できますか? 混乱させて申し訳ないので、私のコードを見てどう思うか教えてください。PrintWriterActionListener

これがプログラム全体です...

import java.util.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.net.*;
public class SimpleChatClient {

    BufferedReader reader;
    PrintWriter writer;
    Socket sock;
    JTextArea chatbox = new JTextArea(10,20);   
    JTextField entertext = new JTextField(20);
    JButton sendchat = new JButton("send");

    public void go(){
        setUpNetworking();
        Thread readerThread1 = new Thread(new IncomingReader());
        readerThread1.start();
        //big probelm. to many setUpNetworkings!!!!!!!!
    }

    public class SendButtonListener implements ActionListener{
        public void actionPerformed (ActionEvent ev){
        try {
                writer.println(entertext.getText());
                writer.flush();
                System.out.println("chat flush");
            }
            catch (Exception ex) {
                ex.printStackTrace();
                System.out.println("action fail");
            }
            entertext.setText("");
            entertext.requestFocus();
        }
    }

    public void setUpNetworking() {
        try {
            sock = new Socket("192.168.0.11", 65534);
            InputStreamReader streamReader = 
                new InputStreamReader(sock.getInputStream());
            reader = new BufferedReader(streamReader);
            writer = new PrintWriter(sock.getOutputStream(), true);
            System.out.println("network established. Beginning mainstream feed.");
        }
        catch (IOException ex) {
            ex.printStackTrace();
            System.out.println("setup fail");
        }
    }


    public class IncomingReader implements Runnable {
        public void run() {
            String message;
            try {
                while ((message = reader.readLine()) != null) {
                    System.out.println("read " + message);
                    chatbox.append(message + "\n");
                    chatbox.append("\n");
                }
            }catch (Exception ex) {
                ex.printStackTrace();
                System.out.println("run fail");
            }
        }
    }
}

Ps 私もこのための GUI プログラムを持っています。これだけで接続が確立されます。

4

1 に答える 1

0

複数のスレッドでのメモリ初期化の問題である可能性があります。フィールドが初期化される前に EDT で読み取られた場合writer、メイン スレッドで初期化されたときにそのスレッドで再度読み取られない可能性があります。

volatile簡単なテストとして、の宣言に追加しwriterます。

于 2011-04-20T06:12:34.027 に答える