1

我正在用 Java 构建一个小型聊天室应用程序。我在这里尝试做的是通过静态 ClientGUI 引用成员发送当前类 ClientGUI 实例(this)。ServerApplication 类应该通过常规的静态 getter(在 ServerApplication.main 中完成)接收当前的 clientGUI 引用。

经过一些令人厌烦的调试后,我仍然无法弄清楚服务器端引用在收到 ClientGUI ref 后为什么仍然为空(getCurrentClientGuiReference() 失败)。

(当然 - 发送的 ref 在传输到服务器端之前被初始化)。

不能通过本地静态 ref 成员传输当前 ref 吗?也许我错过了什么?

波纹管是相关的代码。

提前致谢。

客户端:

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 不会像您认为的那样做。如果客户端和服务器是分开运行的——就像在两个不同的进程和两个不同的 JVM 中——那么再分配任何变量给任何东西都不会使相同的值/对象对客户端和服务器都可见。您必须使用某种方式在进程之间进行通信。

一旦您设法将 ClientGUI 连接到服务器,我怀疑您是否能够以您想要的方式使用它。ClientGUI 也只是一个无法在客户端和服务器之间进行通信的对象。你也必须自己管理。

于 2011-07-28T15:31:43.860 回答
1

据我所知,服务器和客户端处于不同的进程中。它们是完全分开的——在客户端进程中设置一个静态变量不会改变服务器进程中的同一个静态变量。

于 2011-07-28T15:32:07.893 回答
0

我能想到的唯一方法可能适用于您正在尝试做的事情是使用可用于将对象表示为字节序列的序列化,然后可以使用 ObjectOutputStream 发送并根据需要使用 ObjectInputStream 接收在发送/接收对象中。虽然我从事过类似的项目,但我不需要做这样的事情。

于 2014-03-18T06:04:17.213 回答