1

私はJavaで小さなチャットルームアプリを構築しています。ここで私がやろうとしているのは、静的ClientGUI参照メンバーを介して現在のクラスClientGUIインスタンス(this)を送信することです。ServerApplicationクラスは、通常の静的ゲッター(ServerApplication.mainで実行)を介してこの現在のclientGUI参照を受け取ることになっています。

面倒なデバッグを行った後でも、ClientGUI refを受信した後(getCurrentClientGuiReference()が失敗した場合)にサーバー側の参照がnullのままになる理由を理解できません。

(もちろん、送信された参照はサーバー側に転送される前に初期化されます)。

ローカルの静的参照メンバーを介して現在の参照を転送することはできませんか?おそらく私は何かを逃したのですか?

以下は関連するコードです。

前もって感謝します。

クライアント側:

package chatApplication;

import java.net.*;
import java.awt.*;
import java.awt.event.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;

import javax.swing.*;

public class ClientGUI implements StringConsumer, StringProducer 
{

//Graphic components
private JFrame frame;
private JButton btConnect,btSend;

private JTextField tfText, tfServerName, tfPort, tfNickName;
private JPanel north,south,center;
ActionListener listener;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

JLabel mainLable = new JLabel();

//Utilities and connection components
private ConnectionProxy consumer = null;
private ConnectionProxy producer = null;
private ClientDescriptor clientDescriptor = null;

//Connection creation switch
private boolean isConnection = false;

//Client details meant for ClientDescriptor 
static private String nickname = "Noname";
static private String serverAddress = "127.0.0.1";
static private String port = "1300";
static private ClientGUI currentClientGuiReference = null;

public ClientGUI()
{
    frame = new JFrame("Chit & Chat");
    listener = new ActionListener()
    {
        public void actionPerformed(ActionEvent event)
        {
            if (event.getSource() == btConnect)
            {

                if (isConnection == false)
                {
                    ClientGUI.nickname = tfNickName.getText();
                    ClientGUI.serverAddress = tfServerName.getText();
                    ClientGUI.port = tfPort.getText();
                    ClientGUI.currentClientGuiReference = ClientGUI.this;

                    clientDescriptor = new ClientDescriptor(nickname, serverAddress, port, currentClientGuiReference); // Identical though NOT related to serverapplication's clientdescriptor 
                    consumer = new ConnectionProxy(clientDescriptor, ClientGUI.this);

                    //Connecting client consumer as a producer
                    ClientGUI.this.addConsumer(consumer);                       

                    //Temporary text
                    mainLable.setText("Client consumer/producer thread is connected and running!");
                }

            }

            if (event.getSource() == btSend)
            {
                String outGoingMessageToChat = tfText.getText();
                producer.consume(outGoingMessageToChat); //sending outgoing msg to prducer.consume -->  writeutf
            }

        }       
    };

    btConnect = new JButton ("Connect to chat");
    btSend = new JButton ("Send Message");
    btConnect.addActionListener(listener);
    btSend.addActionListener(listener);

    tfText = new JTextField(50);
    tfPort = new JTextField(10);
    tfServerName = new JTextField(20);
    tfNickName = new JTextField(10);
    tfServerName.setText("127.0.0.1");
    tfPort.setText("1300");
    tfNickName.setText("Nickname");

    north = new JPanel();
    south = new JPanel();
    center = new JPanel();
    north.setBackground(Color.blue);
    south.setBackground(Color.gray);
    center.setBackground(Color.white);

    south.add(tfText);
    south.add(btSend);
    north.add(tfNickName,BorderLayout.WEST);
    north.add(tfServerName);
    north.add(tfPort);
    north.add(btConnect,BorderLayout.WEST);


    frame.addWindowListener(new WindowAdapter()
    {
        public void windowClosing (WindowEvent event)
        {
            ClientGUI.this.removeConsumer(clientDescriptor);
            frame.setVisible(false);
            frame.dispose();
            System.exit(0);
        }
    }
    );

    frame.add(north,BorderLayout.NORTH);
    frame.add(center,BorderLayout.CENTER);
    frame.add(south,BorderLayout.SOUTH);
}

public void go()
{
    ClientGUI.currentClientGuiReference = ClientGUI.this;
    frame.setSize(700,700);
    frame.setVisible(true);
    mainLable.setText("Hey! " +
            "Please enter a nickname, Server Address and a port in the text fields above" +
            " and press 'Connect to chat'"); 
    center.add(mainLable);
    frame.add(center, BorderLayout.WEST);
    if (isConnection == true)
    {
        mainLable.setText("Your details were sent.");
    }
}

@Override
public void addConsumer(StringConsumer consumer) 
{
    this.producer = (ConnectionProxy)consumer;

    //All actions completed - client thread producer/consumer is running.
    isConnection = true;
}

@Override
public void removeConsumer(StringConsumer sc) 
{
    consumer.removeConsumer(clientDescriptor);
}

@Override
public void consume(String inComingMessageFromChat) 
{
    //Temporary code
    mainLable.setText(inComingMessageFromChat);
}


public ConnectionProxy getConsumer() 
{
    return consumer;
}

public void setConsumer(ConnectionProxy consumer) 
{
    this.consumer = consumer;
}

/**
 * @param args
 */
public static void main(String[] args) 
{
    ClientGUI clientGUI = new ClientGUI();
    clientGUI.go();
}

public static String getNickname() {return nickname;}

public static String getServerAddress() {return serverAddress;}

public static String getPort() {return port;}

public static ClientGUI getCurrentClientGuiReference() {return currentClientGuiReference;}

}

サーバ側:

package chatApplication;

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

public class ServerApplication {

public static int port = 1300;
public static int backlog = 5;

/**
 * @param args
 */
public static void main(String[] args) 
{


    //Server side network variables
    ServerSocket serverSocket = null;

    //MessageBoard object
    MessageBoard messageBoard = new MessageBoard(); 

    //Client side network variables
    Socket clientSocket = null;
    ClientDescriptor clientDescriptor = null;
    ConnectionProxy clientConnectionProxy = null;

    //Client details meant for ClientDescriptor 
    String clientNickname = "Noname";
    String clientServerAddress = "127.0.0.1";
    String clientPort = "1300";
    ClientGUI clientCurrentGuiReference = null;


    try //Creating Server
    {
        serverSocket = new ServerSocket(port,backlog); //ServerSocket(int port, int backlog) 
    }
    catch(IOException e)
    {
        e.printStackTrace();
    }

    while (true)
    {
        try
        {
            System.out.println("Server is waiting for Client requests...");
            clientSocket = serverSocket.accept(); // A new thread is created for the new client
            System.out.println("Client connection request accepted, creating client connection proxy...");

            clientConnectionProxy = new ConnectionProxy(clientSocket); //connecting client socket to server
            clientConnectionProxy.addConsumer(messageBoard); //Applying specific server system network utilities and connecting proxy to the messageboard

            System.out.println("Requesting Client details from Client side...");

            clientNickname = ClientGUI.getNickname();
            clientServerAddress = ClientGUI.getServerAddress();
            clientPort = ClientGUI.getPort();
            clientCurrentGuiReference = ClientGUI.getCurrentClientGuiReference();

            System.out.println("Creating Client Descriptor...");
            clientDescriptor = new ClientDescriptor(clientNickname, clientServerAddress, clientPort, clientCurrentGuiReference);

            clientDescriptor.addConsumer(messageBoard); 

            messageBoard.addConsumer(clientDescriptor);  

            clientConnectionProxy.start();//Start client connection's thread running
            System.out.println("Client thread started...");
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}
}
4

3 に答える 3

1

staticはあなたが思っていることをしないと思います。クライアントとサーバーが別々に実行されている場合(2つの異なるプロセスと2つの異なるJVMのように)、変数を何かに割り当てても、クライアントとサーバーの両方に同じ値/オブジェクトが表示されることはありません。プロセス間で通信するための何らかの方法を使用する必要があります。

ClientGUIをサーバーに接続できたら、思いどおりに使用できるとは思えません。ClientGUIも、クライアントとサーバー間で通信する機能を持たない単なるオブジェクトです。あなたもそれを自分で管理する必要があります。

于 2011-07-28T15:31:43.860 に答える
1

私が見る限り、サーバーとクライアントは異なるプロセスにあります。これらは完全に分離されています。クライアントプロセスで静的変数を設定しても、サーバープロセスで同じ静的変数が変更されることはありません。

于 2011-07-28T15:32:07.893 に答える