问题描述:

SampleClient.java - does all the client stuff

package sampleclient;

import java.io.*;

import java.net.*;

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

public class SampleClient extends JFrame{

private JTextField userText;

private JTextArea chatWindow;

private ObjectOutputStream user;

private ObjectOutputStream output;

private ObjectInputStream input; //from the server

private String message = "";

private String serverIP;

private Socket connection;

private String name;

private JTextArea contacts;

private PrintWriter toS;

//constructor

public SampleClient(String host, String username){

super("Client");

serverIP = host;

name = username;

userText = new JTextField();

userText.setEditable(false); //not allowed to type while no one is connected

userText.addActionListener(

new ActionListener(){

public void actionPerformed(ActionEvent event){

sendMessage(event.getActionCommand());

userText.setText("");

}

}

);

add(userText, BorderLayout.SOUTH);

contacts = new JTextArea();

chatWindow = new JTextArea();

add(new JScrollPane(contacts), BorderLayout.EAST); //scroll

contacts.append(" ONLINE CONTACTS \n");

add(new JScrollPane(chatWindow), BorderLayout.CENTER); //scroll

setSize(300, 150);

setVisible(true);

}

//connect to server

public void startRunning(){

try {

connectServer();

setupStreams();

whileChatting();

}catch(EOFException eofException){

showMessage("\n Client terminated connection");

}catch (IOException ioException){

ioException.printStackTrace();

}finally{

closeAll();

}

}

//connectServer

private void connectServer() throws IOException{

showMessage("Attempting connection... \n");

connection = new Socket(InetAddress.getByName(serverIP), 6789); //passes to an IP Adrdress and Port Number

showMessage("Connected to:" + connection.getInetAddress().getHostName()); //prompt

toS = new PrintWriter(connection.getOutputStream(), true);

toS.println(name);

}

//set up streams for sending and receive the messages

private void setupStreams()throws IOException{

output = new ObjectOutputStream(connection.getOutputStream());

output.flush();

input = new ObjectInputStream(connection.getInputStream()); //receive messages

showMessage("\n Streams are connected");

}

//actual chat

private void whileChatting()throws IOException{

ableToType(true);

do{

try{

message = (String) input.readObject();

showMessage("\n" +message);

}catch(ClassNotFoundException classNotFoundException){

showMessage("\n ERROR!");

}

}while(!message.equals("SERVER - END"));

}

//close sockets and streams

private void closeAll(){

showMessage("\n Closing connections..");

ableToType(false);

try{

output.close();

input.close();

connection.close();

}catch(IOException ioException){

ioException.printStackTrace();

}

}

//send messages to server

private void sendMessage(String message){

try{

System.out.println(name);

output.writeObject( "\n" + name + ": " + message);

output.flush(); //push bytes

showMessage("\n" + name + ": " + message);

}catch(IOException ioException){

chatWindow.append("ERROR!");

}

}

//Update chatWindow

private void showMessage(final String m){

SwingUtilities.invokeLater(

new Runnable(){

public void run(){

chatWindow.append(m); //appear at the end of the conversation

}

}

);

}

//permission to type to for user

private void ableToType(final boolean tof){

SwingUtilities.invokeLater(

new Runnable(){

public void run(){

userText.setEditable(tof);

}

}

);

}

}

clientTest.java

 package sampleclient;

import javax.swing.*;

public class ClientTest {

public String userName;

private static JFrame frame = new JFrame("Messenger");

private static String getUsername() {

return JOptionPane.showInputDialog(

frame,

"Enter Username:",

"Instant Messenger",

JOptionPane.QUESTION_MESSAGE);

}

public static void main(String[] args){

String username = getUsername();//getting username

SampleClient client;

client = new SampleClient("10.0.1.4", username); //localhost

client.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

client.startRunning();

}

}

SampleServer.java - does all the server stuff

 package sampleserver;

import java.io.*;

import java.net.*;

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import java.util.*;

import java.lang.Object.*;

public class SampleServer extends JFrame{

private JTextField userText; //message variable area

private JTextArea chatWindow; //display the conversation

private ObjectOutputStream output; //output stream->flows from my computer to the other computer

private ObjectInputStream input; //input stream->receive stuff

private ObjectInputStream name; //input stream->receive stuff

private ServerSocket server; //server variable

private Socket connection; //socket variable

private Vector<String> users;

private Vector<String> ips;

private JTextArea conList;

private PrintWriter p;

private BufferedReader fromC;

//constructor

public SampleServer(){

super("Instant Messenger");

userText = new JTextField(); //text field

userText.setEditable(false); //not allowed to type anything if there are no online

userText.addActionListener(

new ActionListener(){

public void actionPerformed (ActionEvent event){

sendMessage(event.getActionCommand()); //sends the message

userText.setText("");

}

}

);

add(userText, BorderLayout.SOUTH);

users = new Vector();

ips = new Vector();

chatWindow = new JTextArea();

conList = new JTextArea();

conList.setEditable(false);

add(new JScrollPane(chatWindow));

add(new JScrollPane(conList), BorderLayout.EAST);

conList.append(" ONLINE USERS \n");

setSize(300, 150);

setVisible(true);

}

//set up and run the server

public void startRunning(){

try {

server = new ServerSocket(6789, 100); //port number and only 100 can connect to the server

while(true){

try{

//connect and have conversation to other client

waitForConnection(); //waiting method

setupStreams(); //set up output and input stream

whileChatting(); //actual chat

}catch(EOFException eofException){

showMessage("\n Server ended the connection!");

}finally {

closeAll();

}

}

}catch(IOException ioException){

ioException.printStackTrace();

}

}

//wait for connection, then display connection information

private void waitForConnection() throws IOException{

showMessage("Waiting for someone to connect...\n");

connection = server.accept(); //once someone asked for connection, accepts this

//showMessage("Now connected to "+connection.getInetAddress().getHostName()); //converts the ip address to string

ips.add(connection.getInetAddress().getHostName()); // adds ip address of client to ips vector

fromC = new BufferedReader(new InputStreamReader(connection.getInputStream())); // gets what client sent through printwriter - username

String s = new String(fromC.readLine()); // saves as string

users.add(s); // saves username of client to users vector

String con = (connection.getInetAddress().getHostName());

showMessage(s + " / " + con + " has connected.");

Iterator c = users.iterator(); // username iterator

Iterator b = ips.iterator(); // ip address iterator

while(c.hasNext()) {

String d = (c.next()).toString(); // gets next element in users vector

String e = (b.next().toString()); // gets next element in ips vector

conList.append(d + "\n"); // displays username in online users list

conList.append("(" + e + ")\n\n"); // displays ip in online users list

}

}

//get stream to send and receive data

private void setupStreams()throws IOException{

output = new ObjectOutputStream(connection.getOutputStream()); //computer who we communicate to

output.flush(); //bytes of information that is send to other person (leftover)

input = new ObjectInputStream(connection.getInputStream()); //receive messages

showMessage("\n Streams are now setup! \n");

}

//actual chat conversation

private void whileChatting() throws IOException{

String message = "You are now connected!";

sendMessage(message);

ableToType(true);

do{

try{

message = (String) input.readObject(); //views it as an object and make sure it's a string

showMessage("\n" + message);

}catch(ClassNotFoundException classNotFoundException){

showMessage("\nError!");

}

}while(!message.equals("CLIENT - END"));

}

//close streams and sockets

private void closeAll(){

showMessage("\n Closing connection... \n");

ableToType(false);

try{

output.close();

input.close();

connection.close();

}catch(IOException ioException){

ioException.printStackTrace();

}

}

//send message to other computer

private void sendMessage(String message){

try{

output.writeObject("SERVER - " +message); //sends the mesage to the output stream

output.flush(); //push extra bytes to user

showMessage("\n SERVER - " + message);

}catch(IOException ioException){

chatWindow.append("\n ERROR!"); //put in the chat area

}

}

//updates chatWindow

private void showMessage(final String text){

SwingUtilities.invokeLater( //updats GUI or threads

new Runnable(){

public void run(){

chatWindow.append(text); //add string at the end of the chatWindow

}

}

);

}

//allow user to type

private void ableToType(final boolean tof){

SwingUtilities.invokeLater( //updats GUI or threads

new Runnable(){

public void run(){

userText.setEditable(tof); //updates the GUI

}

}

);

}

}

serverTest.java

 package sampleserver;

import javax.swing.JFrame;

public class serverTest {

public static void main(String[] args){

SampleServer server = new SampleServer();

server.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

server.startRunning();

}

}

The problem is that we have to do a client-client program and what we did was there are 2 laptops, one for opening the client and server and one for only the client. the 2 laptops successfully connected (client-server) but the client of the laptop with the server can't connect to the chat. Though, if the client of the 2nd laptop is closed, the 1st laptop can connect to its server. Help please?

网友答案:

The problem is that you programmed the chat application for only one computer, as it doesn't create a new Thread for each client, and goes into a while loop until the client disconnects.

//connect and have conversation to other client
waitForConnection(); //waiting method
setupStreams(); //set up output and input stream
whileChatting(); //actual chat //The problem is here, this should have been in a new Thread

Change your SampleServer.java to:

package sampleserver;

import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.lang.Object.*;


public class SampleServer{

    private ObjectOutputStream output; //output stream->flows from my computer to the other computer
    private ObjectInputStream input; //input stream->receive stuff
    private ObjectInputStream name; //input stream->receive stuff
    private Socket connection; //socket variable
    private String user;
    private String ip;
    private PrintWriter p;
    private BufferedReader fromC;
    private serverTest server; //Saves the server test to append messages.

    //constructor
    public SampleServer(Socket c, String username, String userip, serverTest t){  //EDITED!!
        connection = c;
        server = t;
        ip= userip;
        user= username;             
        setupStreams(); //set up output and input stream
    }

    public void run() //This method gets called when Thread starts running
    {
        whileChatting();
        closeAll();
    }

   //get stream to send and receive data
   private void setupStreams(){
       try{
       output = new ObjectOutputStream(connection.getOutputStream()); //computer who we communicate to
       output.flush(); //bytes of information that is send to other person (leftover)
       input = new ObjectInputStream(connection.getInputStream()); //receive messages
       showMessage("\n Streams are now setup! \n");
       }catch(IOException ioException){
           ioException.printStackTrace();

       }
   }

   //actual chat conversation
   private void whileChatting(){
       String message = "You are now connected!";
       sendMessage(message); 
       do{
           try{
               message = (String) input.readObject(); //views it as an object and make sure it's a string
               showMessage("\n" + message);
           }catch(Exception e){
               //showMessage("\nError!");
           }
       }while(!message.equals("CLIENT - END"));

   }

   //close streams and sockets 
   public void closeAll(){
       showMessage("\n Closing connection... \n");
       try{
           output.close();
           input.close();
           connection.close();
       }catch(IOException ioException){
           ioException.printStackTrace();

       }
   }

   //send message to other computer
   public void sendMessage(String message){
       try{
           output.writeObject("SERVER - " +message); //sends the mesage to the output stream
           output.flush(); //push extra bytes to user
       }catch(IOException ioException){
           showMessage("\n ERROR!"); //put in the chat area

       }

   }

   //updates chatWindow
   private void showMessage(String text){
       server.showMessage(text);
   }
}

And change your serverTest.java to:

    package sampleserver;

import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.lang.Object.*;

public class serverTest extends JFrame {
    private JTextField userText; //message variable area
    private JTextArea chatWindow; //display the conversation
    private ServerSocket server; //server variable
    private Vector<String> users;
    private Vector<String> ips;
    private JTextArea conList;
    private ArrayList<SampleServer> connections = new ArrayList<SampleServer>();

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

    public serverTest()
    {
        super("Instant Messenger");
        userText = new JTextField(); //text field
        userText.addActionListener(
                new ActionListener(){
                    public void actionPerformed (ActionEvent event){
                        sendMessage(event.getActionCommand()); //sends the message
                        userText.setText("");
                    }
                }
        );
        add(userText, BorderLayout.SOUTH);
        users = new Vector();
        ips = new Vector();
        chatWindow = new JTextArea();
        conList = new JTextArea();
        conList.setEditable(false);
        add(new JScrollPane(chatWindow));
        add(new JScrollPane(conList), BorderLayout.EAST);
        conList.append("   ONLINE USERS    \n");
        setSize(300, 150);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);

       try {
           server = new ServerSocket(6789, 100); //port number and only 100 can connect to the server
           while(true){
               try{
                    showMessage("Waiting for someone to connect...\n");
                    Socket connection = server.accept(); //once someone asked for connection, accepts this
                    //showMessage("Now connected to "+connection.getInetAddress().getHostName()); //converts the ip address to string

                    ips.add(connection.getInetAddress().getHostName()); // adds ip address of client to ips vector

                    BufferedReader fromC = new BufferedReader(new InputStreamReader(connection.getInputStream())); // gets what client sent through printwriter - username
                    String s = new String(fromC.readLine()); // saves as string
                    users.add(s); // saves username of client to users vector
                    String con = (connection.getInetAddress().getHostName());
                    showMessage(s + " / " + con + " has connected.");

                    Iterator c = users.iterator(); // username iterator
                    Iterator b = ips.iterator(); // ip address iterator

                    conList.setText("");

                    while(c.hasNext()) {

                        String d = (c.next()).toString(); // gets next element in users vector
                        String e = (b.next().toString()); // gets next element in ips vector
                        conList.append(d + "\n"); // displays username in online users list
                        conList.append("(" + e + ")\n\n"); // displays ip in online users list
                    }
                    final SampleServer se = new SampleServer(connection, s, con, this);
                    Thread t = new Thread(new Runnable(){
                        public void run()
                        {
                            se.run();
                        }
                    });
                    connections.add(se);
               }catch(EOFException eofException){
                   showMessage("\n Server ended the connection!");
               }
           }

       }catch(IOException ioException){
           ioException.printStackTrace();
       }
    }

    public void closeAll()
    {
        while (!connections.isEmpty())
        {
            connections.get(0).closeAll();
            connections.remove(0);
        }
    }

    public void sendMessage(String text)
    {
                showMessage("\n SERVER - " + text);
        for (SampleServer s : connections)
        {
            s.sendMessage(text);
        }
    }

    public void showMessage(final String text)
    {
       SwingUtilities.invokeLater( //updats GUI or threads
               new Runnable(){
                   public void run(){
                       chatWindow.append(text); //add string at the end of the chatWindow
                   }
               }
       );
    }
}

Here I moved the GUI code to the main class, and also moved the serversocket to the main class, and made the SampleServer have only one user. When it recieves a message, it adds it to the GUI. Only the server can send messages, and the server doesn't send the clients the user list.

相关阅读:
Top