我遵循了 newboston 教程,并使用服务器端代码和客户端代码创建了一个聊天室。我想在一个应用程序中将它们一起构建。
我的问题是客户端是空白的,我使用了教程中的独立服务器。 服务器聊天与客户端聊天的图片是一个空白窗口 但是如果我先关闭服务器,所有聊天都会出现在客户端聊天中,因为它会立即更新。 客户端聊天更新,显示所有以前的聊天消息。 独立服务器:
package instantmessage;
import javax.swing.JFrame;
public class ServerChatroom {
public static void main(String[] args) {
Server runServer = new Server();
runServer.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
runServer.startServer();
}
}
package instantmessage;
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Server extends JFrame{
private JTextField userText; //where you type in message
private JTextArea chatWindow; //displays the conversation
private ObjectOutputStream output; //information sent to the recipent
private ObjectInputStream input; //information being received from the recipent
private ServerSocket server;
private Socket connection; //the connection between you and the recipent's computer
//setting up GUI.
public Server(){
super("Instant Messanger - Server"); //the piece in the brackets is the title off the app.
userText = new JTextField();
userText.setEditable(false);//without having a connection you can't send messages.
userText.addActionListener(
new ActionListener(){
@Override
public void actionPerformed(ActionEvent event){
sendMessage(event.getActionCommand()); //sends string that was typed into text field.
userText.setText(""); //after text has been sent, remove the previous message sent.
}
}
);
add(userText, BorderLayout.NORTH); //add userText to GUI, make chat window top of the screen.
chatWindow = new JTextArea();
add(new JScrollPane(chatWindow)); //scrolling pane created for all the chats.
setSize(450,200);
setVisible(true);
}
//create the server and run the serve.
public void startServer(){
try{
server = new ServerSocket(6789, 100); //Server socket. first one the server socket, the second how many clients can wait for connection.
while(true){//the loop should run forever. The main program.
try{//connect and allow conversation with another
waitForConnection();//wait for someone to connect with server.
setupStream(); //create the connection between another computer.
whileChatting(); //allow messages to be sent back and forth during chat.
}catch(EOFException eofException){ //whenever the conversation is ended.
showMessage("\n Server overloaded, connection terminated by the server.");
}finally{
closeServer();
}
}
}catch(IOException ioException){
ioException.printStackTrace();
}
}
//wait for connection, after connection established display connection details.
private void waitForConnection() throws IOException{
showMessage("Waiting for connection to be established...\n"); //so user has something to see, knows program isn't frozen.
connection = server.accept(); //accept the connection.
showMessage("Connection established with " + connection.getInetAddress().getHostName());
}
//gets stream for send/receiving of data.
private void setupStream() throws IOException{
output = new ObjectOutputStream(connection.getOutputStream()); //create pathway for connection to other computer.
output.flush(); //good practice. Cleans up data that was "left over"
input = new ObjectInputStream(connection.getInputStream()); //creates pathway to receive data from other PC.
//no flush for input, the other side has to flash.
showMessage("Connection now active");
}
//sending text back and forth
//this receives the data from the connected computer and displays it.
private void whileChatting() throws IOException{
String message = " You are now connected ";
sendMessage(message);
ableToType(true);
do{//have conversation while client doesn't send CLIENT - END.
try{
message = (String) input.readObject(); //read whatever message is incoming.
showMessage("\n" + message);
}catch(ClassNotFoundException classNotFoundException){
showMessage("\n user has sent garbage.");
}
}while(!message.equals("CLIENT - END"));
}
//close streams/sockets after chat ends. "Good housekeeping". Frees up memory.
private void closeServer(){
showMessage("\n\tTerminating connection...");
ableToType(false);
try{
input.close(); //terminate stream from
output.close(); //terminate stream to
connection.close(); //terminate connection
}catch(IOException ioException){
ioException.printStackTrace();
}
}
//send message to connected computer.
private void sendMessage(String message){
try{
output.writeObject("SERVER - " + message); //creates an object of message and sends it along the output stream.
output.flush(); //remove once it's finished sending.
showMessage("\nSERVER - " + message);
}catch(IOException ioException){
chatWindow.append("\n error sending message"); //print out the error in the chat window that the message was not sent.
}
}
//shows messages on main chat area. Updates the chatWindow so it is always current.
private void showMessage(final String string){
SwingUtilities.invokeLater( //creates thread that updates parts of the GUI.
new Runnable(){
public void run(){
chatWindow.append(string);
}
}
);
}
//sets the textfield editable so that the user can type in it
private void ableToType(final boolean bool){
SwingUtilities.invokeLater( //creates thread that updates parts of the GUI.
new Runnable(){
public void run(){
userText.setEditable(bool);
}
}
);
}
}
我的独立代码:
package chatroomomni;
import javax.swing.JFrame;
public class ChatRoomOmni {
public static void main(String[] args) {
MainMenu runProgram = new MainMenu();
runProgram.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
package chatroomomni;
//the user has to chose to be a client or a server.
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
//layout: first button is host server, second line is a JTextLabel telling user to enter server IP, JTextField next to it for server IP, connect button next.
public class MainMenu extends JFrame{
private JButton hostServer = new JButton("Host server");
private JLabel labelEnterServerIP = new JLabel("Enter Server IP: ");
private JTextField serverIPInput = new JTextField(25);
private JButton connectServer = new JButton("Connect to server");
//constructor
public MainMenu(){
super("Instant Messenger - Main Menu");
serverIPInput.setEditable(true);
//action listener for the host server.
hostServer.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event){
Server runServer = new Server();
runServer.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
CloseFrame();
runServer.startServer();
}
});
//action listener for connect to server.
connectServer.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event){
if(!String.valueOf(serverIPInput.getText()).equals("")){
System.out.println(String.valueOf(serverIPInput.getText()));
Client client = new Client(String.valueOf(serverIPInput.getText()));
client.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
CloseFrame();
client.startClient();
}
}
});
setLayout(new FlowLayout());
//add items to frame.
add(hostServer);
add(labelEnterServerIP);
add(serverIPInput);
add(connectServer);
setSize(1000, 500);
setVisible(true);
}
public void CloseFrame(){
super.dispose();
}
}
package chatroomomni;
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Client extends JFrame{
private JTextField userText; //where you type in message
private JTextArea chatWindow; //displays the conversation
private ObjectOutputStream output; //information sent to the recipent
private ObjectInputStream input; //information being received from the recipent
private Socket connection; //the connection between you and the recipent's computer
private String message;
private String serverIP;
public Client(String host){
super("Instant Messenger - Client");
serverIP = host;
userText = new JTextField();
userText.setEditable(false);
userText.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event){
sendMessage(event.getActionCommand());
userText.setText("");
}
});
add(userText, BorderLayout.NORTH);
chatWindow = new JTextArea();
add(new JScrollPane(chatWindow), BorderLayout.CENTER);
setSize(500, 400);
setVisible(true);
}
//connect to the server,
public void startClient(){
try{
connectToServer();
setupStream();
whileChatting();
}catch(EOFException eofException){
showMessage("\n Client terminated the connection");
}catch(IOException ioException){
ioException.printStackTrace();
}finally{
closeClient();
}
}
private void connectToServer() throws IOException{
showMessage("Attempting to connect to server...\n");
connection = new Socket(InetAddress.getByName(serverIP), 6789);
showMessage("Connection established to: " + connection.getInetAddress().getHostAddress());
}
private void setupStream() throws IOException{
output = new ObjectOutputStream(connection.getOutputStream()); //create pathway for connection to other computer.
output.flush(); //good practice. Cleans up data that was "left over"
input = new ObjectInputStream(connection.getInputStream()); //creates pathway to receive data from other PC.
//no flush for input, the other side has to flash.
showMessage("Connection now active");
}
private void whileChatting() throws IOException{
String message = " You are now connected ";
sendMessage(message);
ableToType(true);
do{//have conversation while server doesn't send SERVER - END.
try{
message = (String) input.readObject(); //read whatever message is incoming.
showMessage("\n" + message);
}catch(ClassNotFoundException classNotFoundException){
showMessage("\n server has sent garbage.");
}
}while(!message.equals("SERVER - END") || !message.equals("SERVER - TERMINATE CONNECTION"));
}
private void closeClient(){
showMessage("\n\tTerminating connection...");
ableToType(false);
try{
input.close(); //terminate stream from
output.close(); //terminate stream to
connection.close(); //terminate connection
}catch(IOException ioException){
ioException.printStackTrace();
}
}
private void sendMessage(final String message){
try{
output.writeObject("CLIENT - " + message); //creates an object of message and sends it along the output stream.
output.flush(); //remove once it's finished sending.
showMessage("\nCLIENT - " + message);
}catch(IOException ioException){
chatWindow.append("\n error sending message"); //print out the error in the chat window that the message was not sent.
}
}
private void showMessage(final String string){
SwingUtilities.invokeLater( //creates thread that updates parts of the GUI.
new Runnable(){
public void run(){
chatWindow.append(string);
}
}
);
}
private void ableToType(final boolean bool){
SwingUtilities.invokeLater( //creates thread that updates parts of the GUI.
new Runnable(){
public void run(){
userText.setEditable(bool);
}
}
);
}
}
package chatroomomni;
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Server extends JFrame{
private JTextField userText; //where you type in message
private JTextArea chatWindow; //displays the conversation
private ObjectOutputStream output; //information sent to the recipent
private ObjectInputStream input; //information being received from the recipent
private ServerSocket server;
private Socket connection; //the connection between you and the recipent's computer
//setting up GUI.
public Server(){
super("Instant Messanger - Server"); //the piece in the brackets is the title off the app.
userText = new JTextField();
userText.setEditable(false);//without having a connection you can't send messages.
userText.addActionListener(
new ActionListener(){
@Override
public void actionPerformed(ActionEvent event){
sendMessage(event.getActionCommand()); //sends string that was typed into text field.
userText.setText(""); //after text has been sent, remove the previous message sent.
}
}
);
add(userText, BorderLayout.NORTH); //add userText to GUI, make chat window top of the screen.
chatWindow = new JTextArea();
add(new JScrollPane(chatWindow)); //scrolling pane created for all the chats.
setSize(450,200);
setVisible(true);
}
//create the server and run the serve.
public void startServer(){
try{
server = new ServerSocket(6789, 100); //Server socket. first one the server socket, the second how many clients can wait for connection.
while(true){//the loop should run forever. The main program.
try{//connect and allow conversation with another
waitForConnection();//wait for someone to connect with server.
setupStream(); //create the connection between another computer.
whileChatting(); //allow messages to be sent back and forth during chat.
}catch(EOFException eofException){ //whenever the conversation is ended.
showMessage("\n Server overloaded, connection terminated by the server.");
}finally{
closeServer();
}
}
}catch(IOException ioException){
ioException.printStackTrace();
}
}
//wait for connection, after connection established display connection details.
private void waitForConnection() throws IOException{
showMessage("Waiting for connection to be established...\n"); //so user has something to see, knows program isn't frozen.
connection = server.accept(); //accept the connection.
showMessage("Connection established with " + connection.getInetAddress().getHostName());
}
//gets stream for send/receiving of data.
private void setupStream() throws IOException{
output = new ObjectOutputStream(connection.getOutputStream()); //create pathway for connection to other computer.
output.flush(); //good practice. Cleans up data that was "left over"
input = new ObjectInputStream(connection.getInputStream()); //creates pathway to receive data from other PC.
//no flush for input, the other side has to flash.
showMessage("Connection now active");
}
//sending text back and forth
//this receives the data from the connected computer and displays it.
private void whileChatting() throws IOException{
String message = " You are now connected ";
sendMessage(message);
ableToType(true);
do{//have conversation while client doesn't send CLIENT - END.
try{
message = (String) input.readObject(); //read whatever message is incoming.
showMessage("\n" + message);
}catch(ClassNotFoundException classNotFoundException){
showMessage("\n user has sent garbage.");
}
}while(!message.equals("CLIENT - END"));
}
//close streams/sockets after chat ends. "Good housekeeping". Frees up memory.
private void closeServer(){
showMessage("\n\tTerminating connection...");
ableToType(false);
try{
input.close(); //terminate stream from
output.close(); //terminate stream to
connection.close(); //terminate connection
}catch(IOException ioException){
ioException.printStackTrace();
}
}
//send message to connected computer.
private void sendMessage(String message){
try{
output.writeObject("SERVER - " + message); //creates an object of message and sends it along the output stream.
output.flush(); //remove once it's finished sending.
showMessage("\nSERVER - " + message);
}catch(IOException ioException){
chatWindow.append("\n error sending message"); //print out the error in the chat window that the message was not sent.
}
}
//shows messages on main chat area. Updates the chatWindow so it is always current.
private void showMessage(final String string){
SwingUtilities.invokeLater( //creates thread that updates parts of the GUI.
new Runnable(){
public void run(){
chatWindow.append(string);
}
}
);
}
//sets the textfield editable so that the user can type in it
private void ableToType(final boolean bool){
SwingUtilities.invokeLater( //creates thread that updates parts of the GUI.
new Runnable(){
public void run(){
userText.setEditable(bool);
}
}
);
}
}
上传到 zippyshare 的所有 netbeans 项目文件:www116(dot)zippyshare(dot)com/v/qAa5BGWn/file(dot)html(不允许发布超过 2 个链接,我为试图规避规则而道歉,但这是相关的)
任何帮助,将不胜感激。