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

作者:howard2005 时间:2022-09-01 17:09:20 

一、如何实现TCP通信

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

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

本机的IP地址:192.168.129.222

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

远程机的IP地址:192.168.214.213

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

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

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

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

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

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类

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

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]上启动服务器端

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

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

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

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

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

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

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

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

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

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

来源:https://blog.csdn.net/howard2005/article/details/123573139

标签:Java,TCP,聊天
0
投稿

猜你喜欢

  • Android提高之MediaPlayer音视频播放

    2021-05-29 08:44:37
  • 关于java String中intern的深入讲解

    2023-01-24 18:18:36
  • Mybatis-Plus 条件构造器示例详解

    2023-06-26 06:45:17
  • Linux环境g++编译GDAL动态库操作方法

    2022-02-23 09:41:45
  • java 键盘输入一个数,输出数组中指定元素的示例

    2023-11-24 20:31:14
  • Android5.0+ CollapsingToolbarLayout使用详解

    2022-07-01 01:20:25
  • Java开发工具IntelliJ IDEA安装图解

    2022-06-14 02:30:20
  • 基于Android引入IjkPlayer无法播放mkv格式视频的解决方法

    2023-02-24 22:32:35
  • 一文带你搞懂Java中Get和Post的使用

    2023-04-16 23:57:24
  • Android实现纸飞机的简单操作

    2022-05-16 12:26:04
  • Java 提取照片的EXIF信息批量重命名

    2023-10-05 14:11:28
  • C#多线程之线程池ThreadPool用法

    2021-07-21 06:28:40
  • mybatis plus新增(insert)数据获取主键id的问题

    2023-08-09 10:50:52
  • 细谈java同步之JMM(Java Memory Model)

    2023-11-23 13:09:33
  • OpenHarmony实现类Android短信验证码及倒计时流程详解

    2021-11-14 10:55:26
  • Spring EL表示式的运用@Value说明

    2023-03-05 02:33:19
  • java实现邮件发送

    2022-06-03 02:48:20
  • Android Bitmap和Drawable的对比

    2021-11-16 06:03:41
  • 关于工厂方法模式的Java实现

    2021-12-20 18:06:13
  • java 集合之实现类ArrayList和LinkedList的方法

    2023-09-03 05:41:40
  • asp之家 软件编程 m.aspxhome.com