2

javaを使用して、フォーム、クライアントフォーム、サーバーフォーム、クライアントフォームにTextFieldとボタン(送信ボタン)、サーバーフォームにTextAreaを含む簡単なチャットプログラムを作成しようとしています。

送信ボタンをクリックすると、TextFieldに書き込まれたテキストがサーバーフォームのTextAreaに送信されます。

初めては機能しますが、2回目にボタンをクリックすると機能しません。

これは私がサーバーフォームで使用したコードです:

public class Server extends javax.swing.JFrame implements Runnable {

    private Thread th;

    public Server() {
        initComponents();
        th = new Thread(this);
        th.start();
    }

    // The main method was here

    @Override
    public void run() {

        // Etablir la connexion
        try {
            ServerSocket ecoute;
            ecoute = new ServerSocket(1111);
            Socket service = null;
            System.out.println("Serveur en attente d'un client !");
            while (true) {

                service = ecoute.accept();
                System.out.println("Client connécté !");
                DataInputStream is = new DataInputStream(service.getInputStream());
                jTextArea1.setText("Client dit : "+ is.readUTF().toUpperCase());
                service.close();
            }
        } catch (IOException e) {
            e.printStackTrace();

        }
    }
}

これはクライアントフォームのコードです:

    public class Client extends javax.swing.JFrame {

    DataOutputStream os;

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
        try {
            os.writeUTF(jTextField1.getText());
        } catch (IOException ex) {
            Logger.getLogger(Client.class.getName()).log(Level.SEVERE,null, ex);
        }
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                Client c = new Client();
                c.setVisible(true);

                try {
                    Socket s = new Socket("localhost", 1111);
                    c.os = new DataOutputStream(s.getOutputStream());
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });
    }

}
4

2 に答える 2

1

問題はサーバーのコードにあります。サーバー側でさまざまなクライアントからさまざまなメッセージを受信するには、各受け入れ、つまり各クライアントに対して、TCP 接続を使用しているため、その要求を処理するスレッドを 1 つ作成する必要があります。(-受け入れごとに1つのリクエストのみを処理し、接続を閉じていました)。

コードのソケットに関係のない部分 (つまり、クライアントの GUI に関連するいくつかの不完全な部分) をきれいにしたので、多くの同時クライアント接続でうまく機能する別のバージョンを提示します。最初のメッセージだけでなく、サーバー。

サーバーのコード:

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


public class Server {

    public static void run() {
        try
        {
            ServerSocket ecoute;
            ecoute = new ServerSocket(1111);
            Socket service = null;
            System.out.println("serveur en attente d'un client!");
            while(true)
            {
                service = ecoute.accept();
                System.out.println("client connécté!");
//              ##call a new thread
                WorkerThread wt = new WorkerThread(service);
                wt.start();
            }
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
    }

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


class WorkerThread extends Thread {
    Socket service;
    WorkerThread(Socket service) {
        this.service = service;
    }

    public void run() {
    boolean flag=true;    //you can change this flag's condition, to test if the client disconects
    try
    {
        while (flag){
            DataInputStream is = new DataInputStream(service.getInputStream());
            System.out.println("client dit: " + is.readUTF().toUpperCase());
        }
        service.close();
    }
    catch(IOException e)
        {
            e.printStackTrace();
        }
    }
}

クライアントのコード:

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


public class Client {

DataOutputStream os;

public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {

        public void run() {
               Client c = new Client();
        try {
            Socket s = new Socket("localhost", 1111);
            c.os = new DataOutputStream(s.getOutputStream());
            while (true){
                String str = Input.read_string();
                c.os.writeUTF(str);
            }
        } catch ( IOException e) {
            // TODO auto-generated catch block
            e.printStackTrace();
        }
            }
        });
    }
}

public class Input{
    public static String read_string(){
        String read="";
        try{
            read = new BufferedReader(new InputStreamReader(System.in), 1).readLine();
        }catch (IOException ex){
            System.out.println("error reading from the input stream!");
        }
        return read;
    }
}

その後、おそらくご存じのとおり、サーバーに到着したすべてのメッセージをチャット ルーム内のすべてのクライアントに送信する必要があります。

于 2013-03-03T19:05:38.753 に答える
1

コードのwhile(true)セクションでは、Server一度読んだ後にソケットを閉じていますが、クライアントでは a Socket(および new InputStream) を再度開きません。私が提案するのは、while(true)セクションに別のループがあり、EOF に達するまで新しいデータの読み取りと表示を続けることです。

于 2013-03-03T18:08:57.690 に答える