Java实战之基于TCP实现简单聊天程序

 更新时间:2022年03月19日 08:47:04   作者:howard2005  
这篇文章主要为大家详细介绍了如何在Java中基于TCP实现简单聊天程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

一、如何实现TCP通信

要实现TCP通信需要创建一个服务器端程序和一个客户端程序,为了保证数据传输的安全性,首先需要实现服务器端程序,然后在编写客户端程序。

在本机运行服务器端程序,在远程机运行客户端程序

本机的IP地址:192.168.129.222

远程机的IP地址:192.168.214.213

二、编写C/S架构聊天程序

1.编写服务器端程序 - Server.java

在net.hw.network包里创建Server类

package net.hw.network;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 功能:服务器端
 * 作者:华卫
 * 日期:2022年03月18日
 */
public class Server extends JFrame {
    static final int PORT = 8136;
    static final String HOST_IP = "192.168.129.222";

    private JPanel panel1, panel2;
    private JTextArea txtContent, txtInput, txtInputIP;
    private JScrollPane panContent, panInput;
    private JButton btnClose, btnSend;

    private ServerSocket serverSocket;
    private Socket socket;
    private DataInputStream netIn;
    private DataOutputStream netOut;

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

    public Server() {
        super("服务器");

        //创建组件
        panel1 = new JPanel();
        panel2 = new JPanel();
        txtContent = new JTextArea(15, 60);
        txtInput = new JTextArea(3, 60);
        panContent = new JScrollPane(txtContent, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        panInput = new JScrollPane(txtInput, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        btnClose = new JButton("关闭");
        btnSend = new JButton("发送");

        //添加组件
        getContentPane().add(panContent, "Center");
        getContentPane().add(panel1, "South");
        panel1.setLayout(new GridLayout(0, 1));
        panel1.add(panInput);
        panel1.add(panel2);
        panel2.add(btnSend);
        panel2.add(btnClose);

        //设置组件属性
        txtContent.setEditable(false);
        txtContent.setFont(new Font("宋体", Font.PLAIN, 13));
        txtInput.setFont(new Font("宋体", Font.PLAIN, 15));
        txtContent.setLineWrap(true);
        txtInput.setLineWrap(true);
        txtInput.requestFocus();
        setSize(450, 350);
        setLocation(50, 200);
        setResizable(false);
        setVisible(true);

        //等候客户请求	
        try {
            txtContent.append("服务器已启动...\n");
            serverSocket = new ServerSocket(PORT);
            txtContent.append("等待客户请求...\n");
            socket = serverSocket.accept();
            txtContent.append("连接一个客户。\n" + socket + "\n");
            netIn = new DataInputStream(socket.getInputStream());
            netOut = new DataOutputStream(socket.getOutputStream());
        } catch (IOException e1) {
            e1.printStackTrace();
        }

        /

        //注册监听器,编写事件代码	
        txtContent.addMouseMotionListener(new MouseMotionAdapter() {
            public void mouseMoved(MouseEvent e) {
                displayClientMsg();
            }
        });

        txtInput.addMouseMotionListener(new MouseMotionAdapter() {
            public void mouseMoved(MouseEvent e) {
                displayClientMsg();
            }
        });

        panel2.addMouseMotionListener(new MouseMotionAdapter() {
            public void mouseMoved(MouseEvent e) {
                displayClientMsg();
            }
        });

        txtInput.addKeyListener(new KeyAdapter() {
            public void keyTyped(KeyEvent e) {
                displayClientMsg();
            }
        });

        txtInput.addFocusListener(new FocusAdapter() {
            public void focusGained(FocusEvent e) {
                displayClientMsg();
            }
        });

        btnSend.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {

                    String serverMsg = txtInput.getText();
                    if (!serverMsg.trim().equals("")) {
                        txtContent.append("服务器>" + serverMsg + "\n");
                        netOut.writeUTF(serverMsg);
                    } else {
                        JOptionPane.showMessageDialog(null, "不能发送空信息!", "服务器", JOptionPane.WARNING_MESSAGE);
                    }

                    txtInput.setText("");
                    txtInput.requestFocus();
                } catch (IOException ie) {
                    ie.printStackTrace();
                }
            }
        });

        btnClose.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                try {
                    netIn.close();
                    netOut.close();
                    socket.close();
                    serverSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                System.exit(0);
            }
        });

        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                try {
                    netIn.close();
                    netOut.close();
                    socket.close();
                    serverSocket.close();
                } catch (IOException ie) {
                    ie.printStackTrace();
                }
                System.exit(0);
            }

            public void windowActivated(WindowEvent e) {
                txtInput.requestFocus();
            }
        });
    }

    //显示客户端信息
    void displayClientMsg() {
        try {
            if (netIn.available() > 0) {
                String clientMsg = netIn.readUTF();
                txtContent.append("客户端>" + clientMsg + "\n");
            }
        } catch (IOException e1) {
            e1.printStackTrace();
        }
    }
}

2.编写客户端程序 - Client.java

在net.hw.network包里创建Client类

package net.hw.network;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;

/**
 * 功能:客户端
 * 作者:华卫
 * 日期:2022年03月18日
 */
public class Client extends JFrame {

    private JPanel panel1, panel2;
    private JTextArea txtContent, txtInput;
    private JScrollPane panContent, panInput;
    private JButton btnClose, btnSend;

    private Socket socket;
    private DataInputStream netIn;
    private DataOutputStream netOut;

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

    public Client() {
        super("客户端");

        //创建组件
        panel1 = new JPanel();
        panel2 = new JPanel();
        txtContent = new JTextArea(15, 60);
        txtInput = new JTextArea(3, 60);
        panContent = new JScrollPane(txtContent, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        panInput = new JScrollPane(txtInput, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        btnClose = new JButton("关闭");
        btnSend = new JButton("发送");

        //添加组件
        getContentPane().add(panContent, "Center");
        getContentPane().add(panel1, "South");
        panel1.setLayout(new GridLayout(0, 1));
        panel1.add(panInput);
        panel1.add(panel2);
        panel2.add(btnSend);
        panel2.add(btnClose);

        //设置组件属性
        txtContent.setEditable(false);
        txtContent.setFont(new Font("宋体", Font.PLAIN, 13));
        txtInput.setFont(new Font("宋体", Font.PLAIN, 15));
        txtContent.setLineWrap(true);
        txtInput.setLineWrap(true);
        txtInput.requestFocus();
        setSize(450, 350);
        setLocation(550, 200);
        setResizable(false);
        setVisible(true);

        //连接服务器
        try {
            txtContent.append("连接服务器...\n");
            socket = new Socket(Server.HOST_IP, Server.PORT);
            txtContent.append("连接服务器成功。\n" + socket + "\n");
            netIn = new DataInputStream(socket.getInputStream());
            netOut = new DataOutputStream(socket.getOutputStream());
        } catch (IOException e1) {
            JOptionPane.showMessageDialog(null, "服务器连接失败!\n请先启动服务器程序!", "客户端", JOptionPane.ERROR_MESSAGE);
            System.exit(1);
        }

        /

        //注册监听器,编写事件代码
        txtContent.addMouseMotionListener(new MouseMotionAdapter() {
            public void mouseMoved(MouseEvent e) {
                displayServerMsg();
            }
        });

        txtInput.addMouseMotionListener(new MouseMotionAdapter() {
            public void mouseMoved(MouseEvent e) {
                displayServerMsg();
            }
        });

        panel2.addMouseMotionListener(new MouseMotionAdapter() {
            public void mouseMoved(MouseEvent e) {
                displayServerMsg();
            }
        });

        txtInput.addKeyListener(new KeyAdapter() {
            public void keyTyped(KeyEvent e) {
                displayServerMsg();
            }
        });

        txtInput.addFocusListener(new FocusAdapter() {
            public void focusGained(FocusEvent e) {
                displayServerMsg();
            }
        });

        btnSend.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {

                    String clientMsg = txtInput.getText();
                    if (!clientMsg.trim().equals("")) {
                        netOut.writeUTF(clientMsg);
                        txtContent.append("客户端>" + clientMsg + "\n");
                    } else {
                        JOptionPane.showMessageDialog(null, "不能发送空信息!", "客户端", JOptionPane.WARNING_MESSAGE);
                    }

                    txtInput.setText("");
                    txtInput.requestFocus();
                } catch (IOException ie) {
                    ie.printStackTrace();
                }
            }
        });

        btnClose.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    netIn.close();
                    netOut.close();
                    socket.close();
                } catch (IOException ie) {
                    ie.printStackTrace();
                }
                System.exit(0);
            }
        });

        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                try {
                    netIn.close();
                    netOut.close();
                    socket.close();
                } catch (IOException ie) {
                    ie.printStackTrace();
                }
                System.exit(0);
            }

            public void windowActivated(WindowEvent e) {
                txtInput.requestFocus();
            }
        });
    }

    //显示服务端信息
    void displayServerMsg() {
        try {
            if (netIn.available() > 0) {
                String serverMsg = netIn.readUTF();
                txtContent.append("服务器>" + serverMsg + "\n");
            }
        } catch (IOException e1) {
            e1.printStackTrace();
        }
    }
}

3.测试服务器端与客户端能否通信

在本机[192.168.129.222]上启动服务器端

在远程机[192.168.214.213]上启动客户端

显示连接服务器[192.168.129.222]成功,切换到服务器端查看,显示连接了一个客户[192.168.214.213]

此时,服务器端和客户端就可以相互通信了

4.程序优化思路 - 服务器端采用多线程

其实,很多服务器端程序都是允许被多个应用程序访问的,例如门户网站可以被多个用户同时访问,因此服务器端都是多线程的。

以上就是Java实战之基于TCP实现简单聊天程序的详细内容,更多关于Java TCP聊天程序的资料请关注脚本之家其它相关文章!

相关文章

  • 深入浅析SpringBoot中的自动装配

    深入浅析SpringBoot中的自动装配

    SpringBoot的自动装配是拆箱即用的基础,也是微服务化的前提。接下来通过本文给大家介绍SpringBoot中的自动装配,感兴趣的朋友跟随脚本之家小编一起学习吧
    2018-05-05
  • java如何实现数位分离

    java如何实现数位分离

    这篇文章主要介绍了java如何实现数位分离,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • Java+Swing实现中国象棋游戏

    Java+Swing实现中国象棋游戏

    这篇文章将通过Java+Swing实现经典的中国象棋游戏。文中可以实现开始游戏,悔棋,退出等功能。感兴趣的小伙伴可以跟随小编一起动手试一试
    2022-02-02
  • Java8中List转Map(Collectors.toMap) 的技巧分享

    Java8中List转Map(Collectors.toMap) 的技巧分享

    在最近的工作开发之中,慢慢习惯了很多Java8中的Stream的用法,很方便而且也可以并行的去执行这个流,这篇文章主要给大家介绍了关于Java8中List转Map(Collectors.toMap) 的相关资料,需要的朋友可以参考下
    2021-07-07
  • spring4.3 实现跨域CORS的方法

    spring4.3 实现跨域CORS的方法

    下面小编就为大家分享一篇spring4.3 实现跨域CORS的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-01-01
  • Spring AOP实现Redis缓存数据库查询源码

    Spring AOP实现Redis缓存数据库查询源码

    这篇文章主要介绍了Spring AOP实现Redis缓存数据库查询的相关内容,源码部分还是不错的,需要的朋友可以参考下。
    2017-09-09
  • 详解Java中使用externds关键字继承类的用法

    详解Java中使用externds关键字继承类的用法

    子类使用extends继承父类是Java面向对象编程中的基础知识,这里我们就来详解Java中使用externds关键字继承类的用法,需要的朋友可以参考下
    2016-07-07
  • 每日六道java新手入门面试题,通往自由的道路--多线程

    每日六道java新手入门面试题,通往自由的道路--多线程

    这篇文章主要为大家分享了最有价值的6道多线程面试题,涵盖内容全面,包括数据结构和算法相关的题目、经典面试编程题等,对hashCode方法的设计、垃圾收集的堆和代进行剖析,感兴趣的小伙伴们可以参考一下
    2021-06-06
  • SpringBoot统一数据返回格式的实现示例

    SpringBoot统一数据返回格式的实现示例

    本文主要介绍了SpringBoot统一数据返回格式,它提高了代码的可维护性和一致性,并改善了客户端与服务端之间的通信,具有一定的参考价值,感兴趣的可以了解一下
    2024-05-05
  • Java实现可配置换肤的方法示例

    Java实现可配置换肤的方法示例

    本文主要介绍了Java实现可配置换肤的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06

最新评论