Socket完成聊天程序。

思路分析

使用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) {

}

}

效果展示(有连接数据库,所以有数据)

在这里插入图片描述

在这里插入图片描述
点击其中一个名字。
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_44688861/article/details/105974647