我们的代码现在所做的是有客户端和一个服务器,客户端可以通过服务器发送消息。问题是,我们需要做客户端客户端,因此客户端的消息必须直接转到其他客户端的聊天框。我们只能在服务器聊天框中看到他们在谈论的内容,而不是在客户端的聊天框中。显然它只能做客户端服务器。请帮忙?谢谢!
SampleServer.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author Kim
*/
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
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();
}
}
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);
}
}
ServerTest.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author Kim
*/
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();
}
});
t.start();
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
}
}
);
}
}
clientTest.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author Kim
*/
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("localhost", username); //localhost
client.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
client.startRunning();
}
}
sampleClient.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author Kim
*/
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{
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);
}
}
);
}
}
答案 0 :(得分:0)
使用TCP很难实现它,因为如果你在邻居有10个客户端,那么你必须为每个客户端打开10个端口。如果您认为可以处理它,那么您的系统上应该同时启用ServerSocket
和Socket
,这意味着并行地监听和写入流。
但这可以通过UDP实现,但存在许多限制,UDP并不容易。