Java实战之基于TCP实现简单聊天程序
目录
- 一、如何实现TCP通信
- 二、编写C/S架构聊天程序
- 1.编写服务器端程序 - Server.java
- 2.编写客户端程序 - Client.java
- 3.测试服务器端与客户端能否通信
- 4.程序优化思路 - 服务器端采用多线程
一、如何实现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实现简单聊天程序的详细内容,更多关于Java TCP聊天程序的资料请关注脚本之家其它相关文章!
推荐阅读
- 程序员合集|【Pygame实战】疫情期间给不能出门的你推荐一款爽游 《消灭病毒保卫城市》【强推】愿早日结束
- Pygame合集|Pygame实战(中国象棋人机对抗赛今开战、谁占上风(要不要来一盘试试?))
- 程序员合集|【Pygame实战】如果你是赛车爱好者(这款新赛车游戏分分钟让你上瘾(超跑又是谁的梦想()))
- python合集|Pygame实战(BOOM 这有一款超刺激的扎气球游戏等你来玩~)
- STM32|STM32之俄罗斯方块
- C语言|嵌入式机考笔试之C语言数组问题
- STM32|STM32之LWIP网络协议栈连接腾讯云
- C#项目实战|C#爬虫项目(SWorld阅读)
- C/C++|C For Linux之内存访问-内存简介
- Java|Java面试突击系列(十二)(数据库分库分表的面试连环炮)