zoukankan      html  css  js  c++  java
  • Java 网络通信【01】TCP

      不积跬步,无以至千里;不积小流,无以成江海。——《荀子劝学》

        JAVA中设计网络编程模式的主要有TCP和UDP两种。

        TCP是属于即时通信,点对点连接进行通信。

        UDP是通过数据包来进行通信,UDP当中就会牵扯到数据的解析和传送。

        在安全性能方面,TCP要略胜一筹,通信过程中不容易出现数据丢失的现象,有一方中断,两方的通信就会结束,UDP数据包传送的过程当中,一方中断,数据包有很大的可能丢失,还有可能传来的数据包的顺序是错乱的;

        在效率方面,UDP要比TCP快的不只是一点点的问题,若终端有解析数据方法的函数,数据包就会源源不断的传送过来,然后反馈回去。

    复制代码
    public class Server {
        static BufferedReader br; //服务器端的输入流
        static PrintStream ps; //服务器端的输出流
        static JTextArea text; //服务器相关的界面组件
    
        public Server() {
            JFrame frame = new JFrame("服务器端");
            text = new JTextArea();
            JScrollPane scroll = new JScrollPane(text);
            frame.add(scroll);
            frame.setVisible(true);
            frame.setSize(300, 400);
            text.setEditable(false);
        }
    
        public static void main(String[] args) throws Exception {
            new Server();    //生成服务器界面
            //通过服务器端构造函数  ServerSocket(port) 实例化一个服务器端口
            ServerSocket server = new ServerSocket(2000);
            text.append("监听2000端口" + "
    ");
            Socket client = server.accept();
            br = new BufferedReader(new InputStreamReader(client.getInputStream()));
            ps = new PrintStream(client.getOutputStream());
            String msg;
            //如果输入流不为空,将接受到的信息打印到相应的文本框中并反馈回收到的信息
            while ((msg = br.readLine()) != null) {
                text.append("服务器端收到:" + msg + "
    ");
                ps.println(msg);
                if (msg.equals("quit")) {
                    text.append("客户端“2000”已退出!" + "
    ");
                    text.append("服务器程序将退出!");
                    break;
                }
            }
            ps.close();
            br.close();
            client.close();
        }
    }
    复制代码

     Client类:

    复制代码
    import java.awt.*;
    import java.awt.event.*;
    import java.io.*;
    import javax.swing.*;
    import java.net.*;
    
    public class Client implements ActionListener {
        //这里有两个图形界面,一个是连接的frame,另一个和服务器通信的界面frame1
        private JFrame frame;
        private JLabel adress;
        private JLabel port;
        JTextField adresstext;
        JTextField porttext;
        JButton connect;
    
        private JFrame frame1;
        private JLabel shuru;
        private JPanel panel1;
        private JPanel panel2;
        private JLabel jieshou;
        JButton send;
        static JTextArea shurukuang;
        static TextArea jieshoukuang;
    
        static BufferedReader br1; //从服务端接受的数据流
        static PrintStream ps; //从客户端输出的数据流
        static BufferedReader br2;  //从通信界面中的输入框接受的数据流
        static Socket client;
        //将输入框字符串转换为字符串流所需的字符串的输入流
        static ByteArrayInputStream stringInputStream;
    
        public Client() {
            frame = new JFrame();
            adress = new JLabel("IP 地址");
            port = new JLabel("端口号");
            adresstext = new JTextField("127.0.0.1", 10);
            porttext = new JTextField("2000", 10);
            connect = new JButton("连接");
            //连接界面的布局
            frame.setLayout(new FlowLayout());
            frame.add(adress);
            frame.add(adresstext);
            frame.add(port);
            frame.add(porttext);
            frame.add(connect);
            frame.setVisible(true);
            frame.setSize(200, 150);
            connect.addActionListener(this);
            //通信界面的实例化
            frame1 = new JFrame();
            shuru = new JLabel("请输入");
            shurukuang = new JTextArea("请输入····", 5, 40);
    
            panel1 = new JPanel();
            panel1.add(shuru);
            panel1.add(shurukuang);
            panel1.setLayout(new FlowLayout());
    
            send = new JButton("发送");
            panel2 = new JPanel();
            jieshou = new JLabel("已接受");
    
            jieshoukuang = new TextArea(8, 60);
            jieshoukuang.setEditable(false);
    
            panel2.add(jieshou);
            panel2.add(jieshoukuang);
            panel2.setLayout(new FlowLayout());
            frame1.setLayout(new FlowLayout());
            //通信界面都的布局
            frame1.add(BorderLayout.NORTH, panel1);
            frame1.add(send);
            frame1.add(BorderLayout.SOUTH, panel2);
            //连接时通信界面是处于看不到的
            frame1.setVisible(false);
            frame1.setSize(500, 350);
            send.addActionListener(this);
        }
    
        //两个界面当中都有相应的按钮时间,为相应的时间添加动作
        public void actionPerformed(ActionEvent e) {
            if (e.getSource() == connect) {
                try {
                    //当触发连接按钮时,实例化一个客户端
                    client = new Socket("127.0.0.1", 2000);
                    //隐藏连接界面,显示通信界面
                    frame.setVisible(false);
                    frame1.setVisible(true);
                    jieshoukuang.append("已经连接上服务器!" + "
    ");
                } catch (IOException e1) {
                    System.out.println("链接失败!");
                    e1.printStackTrace();
                }
            }
            //通信界面中的发送按钮相应的时间处理
            if (e.getSource() == send) {
                //将输入框中的字符串转换为字符串流
                stringInputStream = new ByteArrayInputStream((shurukuang.getText()).getBytes());
                br2 = new BufferedReader(new InputStreamReader(stringInputStream));
                String msg;
                try {
                    while ((msg = br2.readLine()) != null) {
                        ps.println(msg);   //将输入框中的内容发送给服务器端
                        jieshoukuang.append("向服务器发送:" + msg + "
    ");
                        jieshoukuang.append("客户端接受相应:" + br1.readLine() + "
    ");
                        if (msg.equals("quit")) {
                            jieshoukuang.append("客户端将退出!");
                            br1.close();
                            ps.close();
                            client.close();
                            frame1.setVisible(false);
                            break;
                        }
                    }
                } catch (IOException e2) {
                    System.out.println("读输入框数据出错!");
                }
                shurukuang.setText("");
            }
        }
    
        public static void main(String[] args) throws IOException {
            new Client();  //实例化连接界面
            client = new Socket("127.0.0.1", 2000);
            br1 = new BufferedReader(new InputStreamReader(client.getInputStream()));     //从服务端接受的数据
            ps = new PrintStream(client.getOutputStream());        //从客户端输出的数据
        }
    }
    复制代码

     写完这两个类以后还是有几个问题:

    1)main 函数为什么非要用 static 来修饰?

    2)缓冲对象 BufferedReader 为什么不能直接用于判断,非要将读到的数据赋值给字符串来进行操作?

    3)在连接界面当中的 Connect 按钮事件 当中我有实例化一个 客户端的对象,但是我注释掉主函数当中 client=new Socket("127.0.0.1",2000); 的这一句的时候,就会发现抛出 NULLPOINTEXCEPTION 异常,我很不理解?

  • 相关阅读:
    远程视频监控之应用篇(mjpg-streamer)
    C语言存储类型
    基于Qt的wifi智能小车的制作(一)
    libevent和基于libevent的网络编程
    fdisk 分区格式化为ext4格式分区
    Makefile 中:= ?= += =的区别
    【计算机网络】详解网络层(二)ARP和RARP
    Nginx 反向代理 负载均衡 虚拟主机配置
    C# 对文本文件的几种读写方法总结
    Visual Studio中Image Watch的使用
  • 原文地址:https://www.cnblogs.com/zhengxingpeng/p/6674340.html
Copyright © 2011-2022 走看看