【Java】GUI界面聊天小程序(基于Socket的客户端服务端通信)

Java 专栏收录该内容
15 篇文章 0 订阅

基于Socket的客户端服务端通信--Java GUI界面小程序

Socket概念及其通信过程:

Socket是TCP/IP中的基本概念,它负责将TCP/IP包发送到指定的IP地址。也可以看成是在两个程序进行通信连接中的一个端点,一个程序将 信息写入Socket中(类似于插座),该Socket将这段信息发送到另一个Socket中(类似于插头),使这段信息能够传送到其他程序。这两端的程序可以是在一台计算机 上,也可以在因特网的远程计算机上。

当两个程序需要通信时,可以使用Socket类建立套接字连接。呼叫的一方称为客户机,负责监听的一方称为服务器。 由于TCP/IP协议是基于连接的、可靠的协议,所以客户机服务器可以在这条连接上可靠地传输数据。服务器所用的套接字是ServerSocket, 客户机所用的套接字是Socket。一个Socket由一个IP地址和一 个端口号唯一确定 。
在传统的UNIX环境下可以操作TCP/IP协议的接口不止Socket一个,Socket 所支持的协议种类也不光TCP/IP -种,因此两者之间是没有必然联系的。在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。
使用Socket 进行Client/Server程序设计的一般连接过程 是这样的: Server 端Listen (监听)某个端口是否有连接请求,Client 端向Server端发出Connect (连接)请求,Server 端向Client端发回Accept (接收)消息。-个连接就建 立起来了。Server 端和Client端都可以通过Send和Write等方法与对方通信。
对于一个功能齐全的Socket,其工作过程包含以下4个基本的步骤。

  1. 创建Socket
  2. 打开连接到Socket的输入/输出流。
  3. 按照一定的协议对Socket进行读写操作。
  4. 关闭Socket。

当用户输入一行文字时,程序将接受数据部分放在线程中,它始终在后台运行,一旦对方发来数据,就立即显示在界面上。而主界面负责输入文字和发送数据,这样发送和接受数据互不影响。

服务端代码:

import java.io.*;
import java.net. *;
import java. awt.event. *;
import java.awt.*;
import javax. swing.*;

public class ChatServer implements ActionListener, Runnable {

    JTextArea showArea;
    JTextField msgText;
    JFrame mainJframe;
    JButton sentBtn;
    JScrollPane JSPane;
    JPanel pane;
    Container con;
    Thread thread = null;
    ServerSocket serverSocket;
    Socket connectToClient;
    DataInputStream inFromClient;
    DataOutputStream outToClient;

    public ChatServer() {
        //设置界面
        mainJframe = new JFrame("聊天——服务端");
        con = mainJframe.getContentPane();
        showArea = new JTextArea();
        showArea.setEditable(false);
        showArea.setLineWrap(true);
        JSPane = new JScrollPane(showArea);
        msgText = new JTextField();
        msgText.setColumns(30);
        msgText.addActionListener(this);
        sentBtn = new JButton("发送");
        sentBtn.addActionListener(this);
        pane = new JPanel();
        pane.setLayout(new FlowLayout());
        pane.add(msgText);
        pane.add(sentBtn);
        con.add(JSPane, BorderLayout.CENTER);
        con.add(pane, BorderLayout.SOUTH);
        mainJframe.setSize(500, 400);
        mainJframe.setVisible(true);
        mainJframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        ;
        try {
            //创建服务套接字
            serverSocket = new ServerSocket(5500);
            showArea.append("正在等待对话请求...\n");//侦听客户端的连接
            connectToClient = serverSocket.accept();
            inFromClient = new DataInputStream(connectToClient.getInputStream());
            outToClient = new DataOutputStream(connectToClient.getOutputStream());
            //启动线程在后台来接收对方的消息
            thread = new Thread(this);
            thread.setPriority(Thread.MIN_PRIORITY);
            thread.start();
        } catch (IOException e) {
            showArea.append("对不起,不能创建服务器\n");
            msgText.setEditable(false);
            sentBtn.setEnabled(false);
        }
    }

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

    @Override
    //响应按钮事件,发送消息给对方
    public void actionPerformed(ActionEvent e) {
        String s = msgText.getText();
        if (s.length() > 0) {
            try {
                outToClient.writeUTF(s);
                outToClient.flush();
                showArea.append("我(服务端)说:" + msgText.getText() + "\n");
                msgText.setText(null);
            } catch (IOException el) {
                showArea.append("你的消息:“" + msgText.getText() + "”未能发出去!\n");
            }
        }
    }

    @Override
    //本线程负责将客户机传来的信息显示在对话区域
    public void run() {
        try{
            while (true){
                showArea.append("客户端说:"+inFromClient.readUTF()+"\n");
                Thread.sleep(1000);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

客户端代码:

import java.io.*;
import java .net.*;
import java. awt.event.*;
import java.awt.*;
import javax. swing.*;

public class ChatClient implements ActionListener,Runnable{
    JTextArea showArea;
    JTextField msgText;
    JFrame mainJframe;
    JButton sentBtn;
    JScrollPane JSPane;
    JPanel pane;
    Container con;
    Thread thread=null;
    Socket connectToServer;
    DataInputStream inFromServer;
    DataOutputStream outToServer;

    public ChatClient(){
        mainJframe=new JFrame("聊天——客户端");
        con=mainJframe.getContentPane();
        showArea=new JTextArea();
        showArea.setEditable(false);
        showArea.setLineWrap(true);
        JSPane=new JScrollPane(showArea);
        msgText=new JTextField();
        msgText.setColumns(30);
        msgText.addActionListener(this);
        sentBtn=new JButton("发送");
        sentBtn.addActionListener(this);

        pane=new JPanel();
        pane.setLayout(new FlowLayout());
        pane.add(msgText);
        pane.add(sentBtn);

        con.add(JSPane, BorderLayout.CENTER);
        con.add(pane, BorderLayout.SOUTH);
        mainJframe.setSize (500 ,400);
        mainJframe.setVisible (true);
        mainJframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //创建套接字连接到服务器
        try{
            connectToServer=new Socket("localhost",5500);
            inFromServer=new DataInputStream(connectToServer.getInputStream());
            outToServer=new DataOutputStream(connectToServer .getOutputStream());
            showArea.append("连接成功,请说话...\n");

            //创建线程在后台处理对方的消息
            thread=new Thread(this);
            thread.setPriority(Thread.MIN_PRIORITY);
            thread.start();
        } catch (UnknownHostException e1){
            e1.printStackTrace();
        } catch (IOException e1){
            showArea.append("抱歉,未能连接到服务器!\n");
            msgText.setEditable(false);
            sentBtn.setEnabled(false);
        }
    }

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


    @Override
    //
    public void actionPerformed(ActionEvent e){
        String s=msgText.getText();
        if (s.length()>0){
            try{
                outToServer.writeUTF(s);
                outToServer.flush();
                showArea.append("我(客户端)说: "+msgText. getText()+"\n");
            } catch (IOException e1){
                showArea.append("你的消息:“"+msgText.getText()+"”未能发送出去!\n");
            }
        }

    }

    //本线程负责将服务器传来的消息显示在对话区域
    public void run(){
        try{
            while (true){
                showArea.append("服务端说:"+inFromServer.readUTF()+"\n");
                Thread.sleep(1000);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


}

编译后首先运行服务端,在运行客户端。截图如下:

在这里插入图片描述

在这里插入图片描述


评论 5 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:点我我会动 设计师:我叫白小胖 返回首页

打赏作者

☄Veni

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值