欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

基于Java的Socket类Tcp网络编程实现实时聊天互动程序(二):Tcp通信的过程及代码编写

程序员文章站 2022-03-23 22:52:55
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、Tcp编程1.为什么需要Socket进行网络通信?2.Socket简介二、服务端过程1.操作的过程2.分步骤编程三、客户端过程1.操作的过程2.分步骤编程四、总结前言本文是作者看完Java前面基础部分跟着一起做的一个学生管理系统,主要就是增删改查四种操作,并未使用到数据库!!!提示:以下是本篇文章正文内容,下面案例可供参考一、Tcp编程计算机网络是指两台或更多的计算机组成的网络,在同一个网络中,任意两台计算机...

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言


一、Tcp编程

计算机网络是指两台或更多的计算机组成的网络,在同一个网络中,任意两台计算机都可以直接通信,因为所有计算机都需要遵循同一种网络协议。

那什么是互联网呢?互联网是网络的网络(internet),即把很多计算机网络连接起来,形成一个全球统一的互联网。

对某个特定的计算机网络来说,它可能使用网络协议ABC,而另一个计算机网络可能使用网络协议XYZ。如果计算机网络各自的通讯协议不统一,就没法把不同的网络连接起来形成互联网。因此,为了把计算机网络接入互联网,就必须使用TCP/IP协议。

TCP/IP协议泛指互联网协议,其中最重要的两个协议是TCP协议和IP协议。只有使用TCP/IP协议的计算机才能够联入互联网,使用其他网络协议(例如NetBIOS、AppleTalk协议等)是无法联入互联网的。

先来演示一下效果,看下图:
基于Java的Socket类Tcp网络编程实现实时聊天互动程序(二):Tcp通信的过程及代码编写
在开发网络应用程序的时候,我们又会遇到Socket这个概念。Socket是一个抽象概念,一个应用程序通过一个Socket来建立一个远程连接,而Socket内部通过TCP/IP协议把数据传输到网络
基于Java的Socket类Tcp网络编程实现实时聊天互动程序(二):Tcp通信的过程及代码编写
Socket、TCP和部分IP的功能都是由操作系统提供的,不同的编程语言只是提供了对操作系统调用的简单的封装。例如,Java提供的几个Socket相关的类就封装了操作系统提供的接口。

1.为什么需要Socket进行网络通信?

因为仅仅通过IP地址进行通信是不够的,同一台计算机同一时间会运行多个网络应用程序,例如浏览器、QQ、邮件客户端等。当操作系统接收到一个数据包的时候,如果只有IP地址,它没法判断应该发给哪个应用程序,所以,操作系统抽象出Socket接口,每个应用程序需要各自对应到不同的Socket,数据包才能根据Socket正确地发到对应的应用程序。

2.Socket简介

一个Socket就是由IP地址和端口号(范围是0~65535)组成,可以把Socket简单理解为IP地址加端口号。端口号总是由操作系统分配,它是一个0~65535之间的数字,其中,小于1024的端口属于特权端口,需要管理员权限,大于1024的端口可以由任意用户的应用程序打开。
基于Java的Socket类Tcp网络编程实现实时聊天互动程序(二):Tcp通信的过程及代码编写使用Socket进行网络编程时,本质上就是两个进程之间的网络通信。其中一个进程必须充当服务器端,它会主动监听某个指定的端口,另一个进程必须充当客户端,它必须主动连接服务器的IP地址和指定端口,如果连接成功,服务器端和客户端就成功地建立了一个TCP连接,双方后续就可以随时发送和接收数据。

因此,当Socket连接成功地在服务器端和客户端之间建立后:

  • 对服务器端来说,它的Socket是指定的IP地址和指定的端口号;
  • 对客户端来说,它的Socket是它所在计算机的IP地址和一个由操作系统分配的随机端口号。
    基于Java的Socket类Tcp网络编程实现实时聊天互动程序(二):Tcp通信的过程及代码编写

二、服务端过程

1.操作的过程

对于服务端而言,该操作步骤有5步:

  1. 先创建一个服务端的套接字
  2. 等待客户端的链接
  3. 获取socket通信的输入流
  4. 获取socket通道的输出流
  5. 关闭serverSocket通道
    结果图基于Java的Socket类Tcp网络编程实现实时聊天互动程序(二):Tcp通信的过程及代码编写

2.分步骤编程

  1. 先创建一个服务端的套接字
ServerSocket serverSocket =  new ServerSocket(8888);
  1. 等待客户端的链接
Socket socket = serverSocket.accept();
  1. 获取socket通信的输入流
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
  1. 获取socket通道的输出流
bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
  1. 关闭serverSocket通道
serverSocket.close();

所有服务端代码:

package Chat;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

//如果一个类需要有界面的显示,该类需要继承JFram
//1.定义JFram窗体中的组件
//2.在构造方法初始化窗体的组件
//3.使用网络编程实现数据的传输(TCP,UDP协议)
//4.实现"发送"按钮的监听事件
public class ServerChatMain extends JFrame implements ActionListener{
    public static void main(String[] args) throws Exception {
        //
        new ServerChatMain();//调用构造方法
    }
    //属性
    //文本域
    private JTextArea jta;
    //滚动条
    private JScrollPane jsp;
    //面板
    private JPanel jp;
    //文本框
    private JTextField jtf;

    //按钮
    private JButton jb;
    //行为

    //输出流
    private BufferedWriter bw = null;

    //构造方法
    public ServerChatMain() throws IOException {
        //初始化组件
        jta = new JTextArea();
        //设置文本与不可编辑
        jta.setEditable(false);
        //注意:需要将文本框添加到滚动条中,实现滚动效果
        jsp = new JScrollPane(jta);
        //面板
        jp = new JPanel();
        //文本框
        jtf = new JTextField(10);
        //按钮
        jb = new JButton("发送");
        //注意:需要将文本框与按钮添加到面板中
        jp.add(jtf);
        jp.add(jb);


        //注意:需要将滚动条与面板全部添加到窗体中
        this.add(jsp, BorderLayout.CENTER);//放在中间
        this.add(jp,BorderLayout.SOUTH);//放在最下面,上北下南

        //注意:需要设置标题,大小,位置,关闭,是否可见
        this.setTitle("QQ聊天服务端");
        this.setSize(300,300);
        this.setLocation(300,300);

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);


        /*******************Tcp服务端开始*********************/

        //给发送按钮绑定一个监听点击事件

        jb.addActionListener(this);//继承一个借口ActionListener

        try{
//       1.创建一个服务端的套接字
           ServerSocket serverSocket =  new ServerSocket(8888);
//
//       2.等待客户端的链接
            Socket socket = serverSocket.accept();

//       3.获取socket通信的输入流
            //InputStream in = socket.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String line = null;

//       4.获取socket通道的输出流

             bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
//
            //循环获取对象
            while((line = br.readLine())!=null){
                //将文本域的数据拼接到文本域中显示
                jta.append(line+System.lineSeparator());
            }
//         5.关闭serverSocket通道
            serverSocket.close();
        }catch (Exception e){
            e.printStackTrace();
        }


        /*******************Tcp服务端开始*********************/


    }

    @Override
    public void actionPerformed(ActionEvent e) {
//        System.out.println("fafa");
        //1.获取文本框中发送的内容
        String text = jtf.getText();
        //2.拼接需要发送的数据内容
        text = "服务端对客户端说:"+text;
//        3.自己也需要显示
        jta.append(text+System.lineSeparator());
        try{
            //4.发送
            bw.write(text);
            bw.newLine();
            bw.flush();

            //5.清空文本框内容
            jtf.setText("");
        }catch (IOException e1){
            e1.printStackTrace();
        }
    }
}

三、客户端过程

1.操作的过程

对于客户端而言,该操作步骤有5步:

  1. 先创建一个客户端的套接字
  2. 获取socket通信的输入流
  3. 获取socket通道的输出流
  4. 关闭serverSocket通道
    结果图:
    基于Java的Socket类Tcp网络编程实现实时聊天互动程序(二):Tcp通信的过程及代码编写

2.分步骤编程

  1. 先创建一个客户端的套接字
Socket socket = new Socket("127.0.0.1",8888);
  1. 获取socket通信的输入流
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));

  1. 获取socket通信的输出流
bw =  new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
  1. 关闭serverSocket通道
socket.close();

所有代码:

package Chat;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

//如果一个类需要有界面的显示,该类需要继承JFram
//1.定义JFram窗体中的组件
//2.在构造方法初始化窗体的组件
public class ClientChatMain extends JFrame implements ActionListener{
    public static void main(String[] args) {
        //
        new ClientChatMain();//调用构造方法
    }
    //属性
    //文本域
    private JTextArea jta;
    //滚动条
    private JScrollPane jsp;
    //面板
    private JPanel jp;
    //文本框
    private JTextField jtf;

    //按钮
    private JButton jb;
    //行为

    //定义输出流
    private  BufferedWriter bw = null;
    //构造方法
    public ClientChatMain(){
        //初始化组件
        jta = new JTextArea();
        //设置文本与不可编辑
        jta.setEditable(false);
        //注意:需要将文本框添加到滚动条中,实现滚动效果
        jsp = new JScrollPane(jta);
        //面板
        jp = new JPanel();
        //文本框
        jtf = new JTextField(10);
        //按钮
        jb = new JButton("发送");
        //注意:需要将文本框与按钮添加到面板中
        jp.add(jtf);
        jp.add(jb);


        //注意:需要将滚动条与面板全部添加到窗体中
        this.add(jsp, BorderLayout.CENTER);//放在中间
        this.add(jp,BorderLayout.SOUTH);//放在最下面,上北下南

        //注意:需要设置标题,大小,位置,关闭,是否可见
        this.setTitle("QQ聊天客户端");
        this.setSize(300,300);
        this.setLocation(300,300);

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);


        /*******************Tcp服务端开始*********************/

        //给发送按钮绑定一个监听事件
        jb.addActionListener(this);
        try{

//        1.创建一个客户端的套接字(尝试链接)
            Socket socket = new Socket("127.0.0.1",8888);

//        2.获取socket通信的输入流
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));


//        3.获取socket通道的输出流
           bw =  new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));


           //循环读取数据,并拼接到文本域中
            String line = null;
            while((line = br.readLine())!=null){
                jta.append(line+System.lineSeparator());
            }

//        4.关闭socket通道
            socket.close();

        }catch (Exception e){
            e.printStackTrace();
        }






        /*******************Tcp服务端开始*********************/

    }

    @Override
    public void actionPerformed(ActionEvent e) {
        //1.获取文本框中需要发送的数据内容
        String text = jtf.getText();

        //2.拼接内容
        text = "客户端对服务端说:" + text;

        //3.自己显示
        jta.append(text+System.lineSeparator());

        try{
            //4.发送
            bw.write(text);
            bw.newLine();
            bw.flush();

            //5.清空文本框内容
            jtf.setText("");

        }catch (Exception e2){
            e2.printStackTrace();
        }

    }
}

四、总结

整体的对话要求已经实现,但是还需要进一步的改进,正常的回车键也可以直接发送,下一章会实现给大家,请继续关注。

mac版本的图案就是不粗,哈哈哈!
基于Java的Socket类Tcp网络编程实现实时聊天互动程序(二):Tcp通信的过程及代码编写

记录时间:2020年11月22日

本文地址:https://blog.csdn.net/weixin_42305672/article/details/109966488