思路分析
使用tcp的话,就需要创建服务器,用来转发各个信息。服务器要可以接受客户端发来的信息,并且根据发送的对象,转发给指定的对象。
需要创建多线程,客户端要绑定个监听事件,可以发送Socket,然后可以接受服务器传来的信息。
服务器代码
import javax.swing.;
import java.io.;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.*;
public class Server extends JFrame implements Runnable {
private Socket socket = null;
private ServerSocket serverSocket = null;
private List list = new ArrayList();
private Map<Integer,Socket> map = new HashMap();//储存多个客户端的线程。
public static Map mapSocket = new HashMap();
private int i = 0;
private BufferedReader bufferedReader = null;
public Server(){
this.setTitle("服务器");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置默认关闭方式
this.setSize(300,300);
this.setVisible(true);
try {
serverSocket= new ServerSocket(9999);//设置服务端的端口
} catch (IOException e) {
e.printStackTrace();
}
new Thread(this).start();
}
@Override
public void run() {
try {
while(true){
socket = serverSocket.accept();//为的是为了多个客户端服务
System.out.println("连接成功");
//InetAddress inetAddress = socket.getLocalAddress();
// System.out.println("地址"+inetAddress.getHostAddress());
map.put(i,socket);
ChatThread chatThread = new ChatThread(socket,map);
list.add(chatThread);
// name = mapSocket.get(socket).toString();
// System.out.println("我的名字是"+name+"请求连接");
i++;
People.id++;
System.out.println("我是people Id"+People.id);
chatThread.start();
}
}catch (IOException e) {
e.printStackTrace();
}
}
class ChatThread extends Thread{
InputStream in = null;
private Socket socket = null;
private BufferedReader bufferedReader = null;
private PrintWriter printWriter = null;
private String str;
ObjectInputStream ois = null;
public ChatThread(Socket socket,Map<Integer,Socket> map){//接受信息,和转发信息
System.out.println("服务客户的线程启动");
this.str = str;
this.socket = socket;
try {
in = socket.getInputStream();
ois = new ObjectInputStream(in);//这个也是包裹的
// bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// printWriter = new PrintWriter(socket.getOutputStream(),true);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
String name = null;
String name2 = null;
String[] nameArray = new String[3];
while (true){
try {
Msg msg = (Msg)ois.readObject();
System.out.println();
// String str = bufferedReader.readLine();//读取客户端来的信息。
Socket target = map.get(msg.getI());
System.out.println("发送给"+msg.getI());
OutputStream outputStream = target.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(outputStream);
oos.writeObject(msg);
//sendMessage(str,name2);//根据信息,发往指定的地方。
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
public void sendMessage(String msg,String name2){
}
}
客户端代码
import javax.swing.;
import java.awt.;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
public class Client extends JFrame implements Runnable {
private JTextArea ta = new JTextArea();
private JTextField tf = new JTextField();
private String name = null;
private InputStream in = null;
OutputStream os = null;
ObjectOutputStream oos = null;
ObjectInputStream oi = null;
int id = 0;
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
private String name2 = null;
private Socket socket = null;
public Client(String name,String name2,int id){
this.add(ta,BorderLayout.CENTER);
this.add(tf,BorderLayout.SOUTH);
this.name2 = name2;
this.id = id;
this.setTitle(name);
this.name = name;
tf.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
// PrintWriter printWriter = new PrintWriter(socket.getOutputStream(),true);
// printWriter.println(name+":"+tf.getText()+":"+name2);
Msg msg = new Msg();
msg.setI(id);
System.out.println("我设置了id"+id);
msg.setContent(tf.getText());
msg.setName(name);
msg.setName2(name2);
ta.append(name+":"+tf.getText()+"\n");
oos.writeObject(msg);//发送信息
tf.setText("");
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(300,300);
this.setVisible(true);
try {
socket = new Socket("127.0.0.1",9999);
os = socket.getOutputStream();
oos = new ObjectOutputStream(os);
} catch (IOException e) {
e.printStackTrace();
}
Server.mapSocket.put(socket,"123");
new Thread(this).start();
}
@Override
public void run() {
try {
while(true) {
//BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));//目的是读取sock发来的信息
//System.out.println("我运行了");
// String s = bufferedReader.readLine();
try {
in = socket.getInputStream();//每次调用的时候,创建连接。不写在这里就不行。
oi = new ObjectInputStream(in);
Msg msg = (Msg)oi.readObject();;//接收连接
System.out.println(msg.getContent());
ta.append( msg.getName()+":"+msg.getContent()+"\n");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
显示界面(外加调用)
import javax.swing.;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
public class ShowPeople extends JFrame implements ActionListener {
private String name = null ;//选中要交流的对象。
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
public ShowPeople(){
String name4=JOptionPane.showInputDialog("输入昵称:");
UserDao userDao = new UserDao();
List list = userDao.showUser();
JButton[] buttons = new JButton[list.size()];
String[] columnName = {"名字","性别"};
String[][] tableVlues = new String[list.size()][2];
for(int i = 0;i<list.size();i++){
tableVlues[i][0] = list.get(i).toString();
tableVlues[i][1] = "";
}
JTable jTable = new JTable(tableVlues,columnName);
jTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
int i = 0;
@Override
public void valueChanged(ListSelectionEvent listSelectionEvent) {
i++;
int row = jTable.getSelectedRow();
int column = jTable.getSelectedColumn();
name = jTable.getValueAt(row,column).toString();
dispose();
if(i == 1){//因为每次点击JTable会运行两次,所以为了防止运行两次。
int id = 0;
People.map.put(name4,id);//People中的map是记录名字和id,因为服务器每次连接,就会使用i于这个socket绑定,然后i++。
id++;
People.map.put(name,id);
id++;
int id2 = (int)People.map.get(name);
int id3 = (int)People.map.get(name4);
Client client = new Client(name4,name,id2);//最后面的那个参数是要建立通讯的id标识
Client client1 = new Client(name,name4,id3);
}
}
});
JScrollPane scrollPane = new JScrollPane(jTable);
getContentPane().add(scrollPane,BorderLayout.CENTER);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(300,300);
this.setVisible(true);
}
public static void main(String[] args) {
new ShowPeople();
}
@Override
public void actionPerformed(ActionEvent actionEvent) {
}
}
效果展示(有连接数据库,所以有数据)
点击其中一个名字。