服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - Java实战之基于TCP实现简单聊天程序

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

2022-10-10 14:58howard2005 Java教程

这篇文章主要为大家详细介绍了如何在Java中基于TCP实现简单聊天程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

一、如何实现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实现简单聊天程序

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

原文链接:https://blog.csdn.net/howard2005/article/details/123573139

延伸 · 阅读

精彩推荐
  • Java教程浅析Java随机数与定时器

    浅析Java随机数与定时器

    本篇文章给大家分析了Java随机数与定时器的实现原理以及代码分享,有需要的读者参考下吧。...

    彬菌6322021-04-06
  • Java教程全面了解JAVA_BaseDAO数据处理类

    全面了解JAVA_BaseDAO数据处理类

    下面小编就为大家带来一篇全面了解JAVA_BaseDAO数据处理类。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧 ...

    jingxian2022020-05-28
  • Java教程Java设计模式之java观察者模式详解

    Java设计模式之java观察者模式详解

    这篇文章主要介绍了Java经典设计模式之观察者模式,简单分析了观察者模式的概念、原理并结合实例形式给出了java观察者模式的具体用法与相关注意事项...

    大忽悠爱忽悠10562022-01-04
  • Java教程新手初学Java-Map

    新手初学Java-Map

    Map简介:将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。此接口取代 Dictionary 类,后者完全是一个抽象类,而不是一个...

    N0lan8622021-09-29
  • Java教程Spring Web项目spring配置文件随服务器启动时自动加载

    Spring Web项目spring配置文件随服务器启动时自动加载

    这篇文章主要介绍了Spring Web项目spring配置文件随服务器启动时自动加载,加载spring的配置文件,并且只加载一次,从而提高程序效率。具体内容详情大家通...

    linuxidc9722021-03-19
  • Java教程Java 线程相关总结

    Java 线程相关总结

    这篇文章主要介绍了Java 线程的相关资料,帮助大家更好的理解和学习使用Java,感兴趣的朋友可以了解下...

    心悦君兮君不知-睿11462021-08-16
  • Java教程详解spring cloud分布式整合zipkin的链路跟踪

    详解spring cloud分布式整合zipkin的链路跟踪

    这篇文章主要介绍了详解spring cloud分布式整合zipkin的链路跟踪,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    IT高飞7642021-05-20
  • Java教程java的split方法使用示例

    java的split方法使用示例

    这篇文章主要介绍了java的split方法使用示例,需要的朋友可以参考下 ...

    java教程网3162019-11-18