0


Java案例:基于TCP的简单聊天程序

文章目录

一、如何实现TCP通信

  • 要实现TCP通信需要创建一个服务器端程序和一个客户端程序,为了保证数据传输的安全性,首先需要实现服务器端程序,然后在编写客户端程序。
  • 在本机运行服务器端程序,在远程机运行客户端程序
  • 本机的IP地址:192.168.129.222在这里插入图片描述
  • 远程机的IP地址:192.168.214.213在这里插入图片描述

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

(一)编写服务器端程序 - 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日
 */publicclassServerextendsJFrame{staticfinalint PORT =8136;staticfinal 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;publicstaticvoidmain(String[] args){newServer();}publicServer(){super("服务器");//创建组件
        panel1 =newJPanel();
        panel2 =newJPanel();
        txtContent =newJTextArea(15,60);
        txtInput =newJTextArea(3,60);
        panContent =newJScrollPane(txtContent, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        panInput =newJScrollPane(txtInput, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        btnClose =newJButton("关闭");
        btnSend =newJButton("发送");//添加组件getContentPane().add(panContent,"Center");getContentPane().add(panel1,"South");
        panel1.setLayout(newGridLayout(0,1));
        panel1.add(panInput);
        panel1.add(panel2);
        panel2.add(btnSend);
        panel2.add(btnClose);//设置组件属性
        txtContent.setEditable(false);
        txtContent.setFont(newFont("宋体", Font.PLAIN,13));
        txtInput.setFont(newFont("宋体", 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 =newServerSocket(PORT);
            txtContent.append("等待客户请求...\n");
            socket = serverSocket.accept();
            txtContent.append("连接一个客户。\n"+ socket +"\n");
            netIn =newDataInputStream(socket.getInputStream());
            netOut =newDataOutputStream(socket.getOutputStream());}catch(IOException e1){
            e1.printStackTrace();}///注册监听器,编写事件代码    
        txtContent.addMouseMotionListener(newMouseMotionAdapter(){publicvoidmouseMoved(MouseEvent e){displayClientMsg();}});

        txtInput.addMouseMotionListener(newMouseMotionAdapter(){publicvoidmouseMoved(MouseEvent e){displayClientMsg();}});

        panel2.addMouseMotionListener(newMouseMotionAdapter(){publicvoidmouseMoved(MouseEvent e){displayClientMsg();}});

        txtInput.addKeyListener(newKeyAdapter(){publicvoidkeyTyped(KeyEvent e){displayClientMsg();}});

        txtInput.addFocusListener(newFocusAdapter(){publicvoidfocusGained(FocusEvent e){displayClientMsg();}});

        btnSend.addActionListener(newActionListener(){publicvoidactionPerformed(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(newActionListener(){publicvoidactionPerformed(ActionEvent arg0){try{
                    netIn.close();
                    netOut.close();
                    socket.close();
                    serverSocket.close();}catch(IOException e){
                    e.printStackTrace();}
                System.exit(0);}});addWindowListener(newWindowAdapter(){publicvoidwindowClosing(WindowEvent e){try{
                    netIn.close();
                    netOut.close();
                    socket.close();
                    serverSocket.close();}catch(IOException ie){
                    ie.printStackTrace();}
                System.exit(0);}publicvoidwindowActivated(WindowEvent e){
                txtInput.requestFocus();}});}//显示客户端信息voiddisplayClientMsg(){try{if(netIn.available()>0){
                String clientMsg = netIn.readUTF();
                txtContent.append("客户端>"+ clientMsg +"\n");}}catch(IOException e1){
            e1.printStackTrace();}}}

(二)编写客户端程序 - 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日
 */publicclassClientextendsJFrame{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;publicstaticvoidmain(String[] args){newClient();}publicClient(){super("客户端");//创建组件
        panel1 =newJPanel();
        panel2 =newJPanel();
        txtContent =newJTextArea(15,60);
        txtInput =newJTextArea(3,60);
        panContent =newJScrollPane(txtContent, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        panInput =newJScrollPane(txtInput, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        btnClose =newJButton("关闭");
        btnSend =newJButton("发送");//添加组件getContentPane().add(panContent,"Center");getContentPane().add(panel1,"South");
        panel1.setLayout(newGridLayout(0,1));
        panel1.add(panInput);
        panel1.add(panel2);
        panel2.add(btnSend);
        panel2.add(btnClose);//设置组件属性
        txtContent.setEditable(false);
        txtContent.setFont(newFont("宋体", Font.PLAIN,13));
        txtInput.setFont(newFont("宋体", 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 =newSocket(Server.HOST_IP, Server.PORT);
            txtContent.append("连接服务器成功。\n"+ socket +"\n");
            netIn =newDataInputStream(socket.getInputStream());
            netOut =newDataOutputStream(socket.getOutputStream());}catch(IOException e1){
            JOptionPane.showMessageDialog(null,"服务器连接失败!\n请先启动服务器程序!","客户端", JOptionPane.ERROR_MESSAGE);
            System.exit(1);}///注册监听器,编写事件代码
        txtContent.addMouseMotionListener(newMouseMotionAdapter(){publicvoidmouseMoved(MouseEvent e){displayServerMsg();}});

        txtInput.addMouseMotionListener(newMouseMotionAdapter(){publicvoidmouseMoved(MouseEvent e){displayServerMsg();}});

        panel2.addMouseMotionListener(newMouseMotionAdapter(){publicvoidmouseMoved(MouseEvent e){displayServerMsg();}});

        txtInput.addKeyListener(newKeyAdapter(){publicvoidkeyTyped(KeyEvent e){displayServerMsg();}});

        txtInput.addFocusListener(newFocusAdapter(){publicvoidfocusGained(FocusEvent e){displayServerMsg();}});

        btnSend.addActionListener(newActionListener(){publicvoidactionPerformed(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(newActionListener(){publicvoidactionPerformed(ActionEvent e){try{
                    netIn.close();
                    netOut.close();
                    socket.close();}catch(IOException ie){
                    ie.printStackTrace();}
                System.exit(0);}});addWindowListener(newWindowAdapter(){publicvoidwindowClosing(WindowEvent e){try{
                    netIn.close();
                    netOut.close();
                    socket.close();}catch(IOException ie){
                    ie.printStackTrace();}
                System.exit(0);}publicvoidwindowActivated(WindowEvent e){
                txtInput.requestFocus();}});}//显示服务端信息voiddisplayServerMsg(){try{if(netIn.available()>0){
                String serverMsg = netIn.readUTF();
                txtContent.append("服务器>"+ serverMsg +"\n");}}catch(IOException e1){
            e1.printStackTrace();}}}

(三)测试服务器端与客户端能否通信

  • 在本机[192.168.129.222]上启动服务器端在这里插入图片描述
  • 在远程机[192.168.214.213]上启动客户端在这里插入图片描述
  • 显示连接服务器[192.168.129.222]成功,切换到服务器端查看,显示连接了一个客户[192.168.214.213]在这里插入图片描述
  • 此时,服务器端和客户端就可以相互通信了在这里插入图片描述

(四)程序优化思路 - 服务器端采用多线程

  • 其实,很多服务器端程序都是允许被多个应用程序访问的,例如门户网站可以被多个用户同时访问,因此服务器端都是多线程的。在这里插入图片描述
标签: java tcp/ip

本文转载自: https://blog.csdn.net/howard2005/article/details/123573139
版权归原作者 howard2005 所有, 如有侵权,请联系我们删除。

“Java案例:基于TCP的简单聊天程序”的评论:

还没有评论