本程序实现了多客户端通过服务器进行通讯的目的,但是在将消息输入从控制台(使用scanner输入)转为从JtextField输入时出现问题。
/*服务端代码*/
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Server:
*/
public class Server {
public static List<String> l = new ArrayList();//store who have connected
public static void main(String[] args) {
//store Client thread and protect them
Vector<UserThread> vector = new Vector <>();
//use thread poll to manage the thread
ExecutorService es = Executors.newFixedThreadPool(5);
try {
ServerSocket server = new ServerSocket(8888);
System.out.println("Server is Running,Wating for Client.....");
while(true){
//accept Client
Socket socket = server.accept();
//create a new thread for every Client task.
UserThread user = new UserThread(socket,vector);
es.execute(user);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* Client ManageThread:
*/
class UserThread implements Runnable{
private String name; //Client name,unique
private Socket socket;
private Vector<UserThread> vector; //Set of Client
private ObjectInputStream oIn;
private ObjectOutputStream oOut;
private boolean flag = true; //tag
public UserThread(Socket socket, Vector<UserThread> vector) {
this.socket = socket;
this.vector = vector;
vector.add(this); //add nowtime's thread to vector
}
@Override
public void run() {
try {
//Create inputStream and outputStream
System.out.println("Client:" + socket.getInetAddress().getHostAddress() + " is Connected!");
oIn = new ObjectInputStream(socket.getInputStream());
oOut = new ObjectOutputStream((socket.getOutputStream()));
//2、Loop to read
while(flag){
//Read object
Message message = (Message)oIn.readObject();
//Get Type
int type = message.getType();
//judge
switch (type){
//if it is information
case MessageType.TYPE_SEND:
String to = message.getTo();
UserThread ut;
//To Find the Client you want to send message
int size = vector.size();
for (int i = 0; i < size; i++) {
ut = vector.get(i);
//if find and not yourself
if(to.equals(ut.name) && ut != this){
ut.oOut.writeObject(message);
}
}
break;
//if it's login
case MessageType.TYPE_LOGIN:
name = message.getFrom();//Get the Client name
Server.l.add(name);
String[] s = Server.l.toArray(new String[Server.l.size()]);//getAllClientName
message.setInfo("Welcom!");//show the successful message
message.setClientName(s);
oOut.writeObject(message);
break;
}
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
/*message类*/
import java.io.Serializable;
/**
* Message
*/
public class Message implements Serializable {
private static final long serialVersionUID = 1L;
private String from;
private String to;
private int type;
private String info;
private String[] clientName;
public Message() {
}
public Message(String from, String to, int type, String info) {
this.from = from;
this.to = to;
this.type = type;
this.info = info;
}
public Message(String from, String to, int type, String info,String[] clientName) {
this.from = from;
this.to = to;
this.type = type;
this.info = info;
this.clientName=clientName;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
public void setClientName(String [] clientName) {
this.clientName=clientName;
}
public String[] getClientName(String [] clientName) {
return clientName;
}
}
public class MessageType {
public static final int TYPE_LOGIN = 0x1; //to login
public static final int TYPE_SEND = 0x2; //to send Info
}
下面是出现问题的客户端代码:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Client:
*/
public class Client extends JFrame {
JTextField tf = new JTextField();//input
JTextArea ta1 = new JTextArea();//show info
JTextArea ta2 = new JTextArea();//show Client
Container cc;
JPanel jp1 = new JPanel(new GridLayout(1, 2));
JScrollPane jScrollPane;
Socket socket;
ObjectOutputStream oOut;
ObjectInputStream oIn;
Message message;
Scanner input;
String name;
String[] ss= new String[2];
public Client() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cc = this.getContentPane();
setTitle("Client");
setBounds(450, 100, 1000, 800);
ta1.setBorder(BorderFactory.createEtchedBorder());
ta2.setBorder(BorderFactory.createEtchedBorder());
jp1.setBorder(BorderFactory.createEtchedBorder());
jp1.add(ta1);
jp1.add(ta2);
jScrollPane = new JScrollPane(jp1);
cc.add(jScrollPane, BorderLayout.CENTER);
cc.add(tf, BorderLayout.SOUTH);
setVisible(true);
tf.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String s = tf.getText();
ss =s.split("\\s+");
//Create Message
message = new Message();
//Send to who?
message.setTo(ss[0]);
//From me
message.setFrom(name);
//Type
message.setType(MessageType.TYPE_SEND);
//Information
message.setInfo(ss[1]);
/*----The object is finished----*/
//send it to Server
try {
oOut.writeObject(message);
} catch (IOException p) {
p.printStackTrace();
}
ta1.append(tf.getText()+"\n");
ta1.setSelectionEnd(ta1.getText().length());
ta1.append("please input To: and Info:\n");
tf.setText("");
}
});
}
public void connect() {
ExecutorService es = Executors.newSingleThreadExecutor();
input = new Scanner(System.in);
try {
socket = new Socket("localhost", 8888);
} catch (IOException e) {
e.printStackTrace();
}
ta1.append("Server is Successfully Connected!\n");
try {
oOut = new ObjectOutputStream(socket.getOutputStream());
oIn = new ObjectInputStream(socket.getInputStream());
//1.Client login
//Send the login information to server
ta1.append("Please input name:\n");
name = input.nextLine();
//only give the name and type
message = new Message(name, null, MessageType.TYPE_LOGIN, null);
//send to server
oOut.writeObject(message);
//server return message to welcome
message = (Message) oIn.readObject();
//print the message in client window
ta1.append(message.getInfo() + message.getFrom()+"\n");
//
for(int i=0;i<message.getClientName().length;i++){
ta2.append("Client:"+message.getClientName()[i]+"\n");
}
ta2.append("The Clients above is connected!");
es.execute(new readInfoThread(oIn));
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public void getServer() {
// //3.Send message
// //use main thread
// boolean flag = true;
// //Loop
// while (flag) {
// //Create object to send
// message = new Message();
// //to ?
// ta1.append("To:\n");
// message.setTo(input.nextLine());
// //from ?
// message.setFrom(this.name);
// //type of message
// message.setType(MessageType.TYPE_SEND);
// //Info
// ta1.append("Info:\n");
// message.setInfo(input.nextLine());
// /*----a message is created----*/
// //send it to Server
// try {
// oOut.writeObject(message);
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
}
public static void main(String[] args) {
Client client = new Client();
client.connect();
//client.getServer();
}
/**
* ReadInfo from other Client
*/
class readInfoThread implements Runnable {
private ObjectInputStream oIn;
private boolean flag = true; //tag
public readInfoThread(ObjectInputStream oIn) {
this.oIn = oIn;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
@Override
public void run() {
try {
//Loop to read info
while (flag) {
//Read
Message message = (Message) oIn.readObject();
//Show Info in window
ta1.append("[" + message.getFrom() + "]send message to me:\n"+ message.getInfo()+"\n");
}
//close all
if (oIn != null) {
oIn.close();
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
也就是说将上面客户端获取输入信息(getServer方法)的方式转变为Text输入(tf的ActionListener)后,
另一个客户端无法接收到消息(或者可能是消息根本没有被message获取)。