Java学习笔记39——网络编程03

2023-09-18 21:52:04

TCP通信程序

TCP通信原理

TCP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket对象,从而在通信的两端形成网络虚拟链路,一旦建立了虚拟的网络链路,两端的程序就可以通过虚拟链路进行通信

Java对基于TCP协议的的网络提供了良好的封装,使用Socket对象来代表两端的通信端口,并通过Socket产生O流来进行网络通信

TCP发送数据的步骤

  1. 创建客户端的socket对象(Socket)
    Socket(String host,int port)
  2. 获取输出流,写数据
    OutputStream getOutputStream()
  3. 释放资源
    void close()
public class ClientDemo {
    public static void main(String[] args) throws IOException {
        //创建客户端的Socket
        //Socket s=new Socket(InetAddress.getByName("127.0.0.1"),10000);
        Socket s=new Socket("127.0.0.1",10000);
        //获取输出流写数据
        OutputStream os=s.getOutputStream();
        os.write("Hello TCP!".getBytes());
        s.close();
    }
}

TCP接收数据的步骤

  1. 创建服务器端的socket对象(ServerSocket)
    ServerSocket(int port)
  2. 监听客户端连接,返回一个对应的Socket对象
    Socket accept()
  3. 获取输入流,读数据,并把数据显示在控制台
    InputStream getInputStream()
  4. 释放资源
    void close()
public class ServerDemo {
    public static void main(String[] args) throws IOException {
        ServerSocket ss=new ServerSocket(10000);
        Socket s=ss.accept();
        InputStream is=s.getInputStream();
        byte[] bys=new byte[1024];
        int len=is.read(bys);
        String data=new String(bys,0,len);
        System.out.println(data);
        s.close();
        ss.close();
    }
}

TCP通讯程序练习

练习1

  • 客户端:发送数据,接收服务器反馈
  • 服务器:接收数据,给出反馈
public class ClientDemo {
    public static void main(String[] args) throws IOException {
        //创建客户端的Socket
        //Socket s=new Socket(InetAddress.getByName("127.0.0.1"),10000);
        Socket s=new Socket("127.0.0.1",10000);
        //获取输出流写数据
        OutputStream os=s.getOutputStream();
        os.write("Hello TCP!".getBytes());
        //接收服务器的反馈
        InputStream is=s.getInputStream();
        byte[] bys=new byte[1024];
        int len=is.read(bys);
        String data=new String(bys,0,len);
        System.out.println("客户端:"+data);
        s.close();
    }
}

public class ServerDemo {
    public static void main(String[] args) throws IOException {
        ServerSocket ss=new ServerSocket(10000);
        Socket s=ss.accept();
        InputStream is=s.getInputStream();
        byte[] bys=new byte[1024];
        int len=is.read(bys);
        String data=new String(bys,0,len);
        System.out.println("服务器:"+data);
        //给反馈
        OutputStream os=s.getOutputStream();
        os.write("已经收到!".getBytes());
        ss.close();
    }
}

练习2

  • 数据来源于键盘录入,直到886结束
  • 接收数据在控制台输出
public class ClientDemo {
    public static void main(String[] args) throws IOException {
        //创建客户端的Socket
        //Socket s=new Socket(InetAddress.getByName("127.0.0.1"),10000);
        Socket s=new Socket("127.0.0.1",10000);
        //数据来自键盘录入
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        //封装输出流对象,用字符流传输
        BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        String line;
        while((line=br.readLine())!=null){
            if("886".equals(line))
                break;
            bw.write(line);
            bw.newLine();
            bw.flush();
//            OutputStream os=s.getOutputStream();
//            os.write(line.getBytes());
        }
        s.close();
    }
}
public class ServerDemo {
    public static void main(String[] args) throws IOException {
        ServerSocket ss=new ServerSocket(10000);
        Socket s=ss.accept();
        InputStream is=s.getInputStream();
        InputStreamReader isr=new InputStreamReader(is);
        BufferedReader br=new BufferedReader(isr);
        String line;
        while((line=br.readLine())!=null){
        System.out.println("服务器:"+line);
        }

        ss.close();
    }
}

练习3

服务器将接收到的文本写入文件

public class ServerDemo {
    public static void main(String[] args) throws IOException {
        ServerSocket ss=new ServerSocket(10010);
        Socket s=ss.accept();
        InputStream is=s.getInputStream();
        InputStreamReader isr=new InputStreamReader(is);
        BufferedReader br=new BufferedReader(isr);
        BufferedWriter bw=new BufferedWriter(new FileWriter("s.txt"));
        String line;
        while((line=br.readLine())!=null){
            bw.write("服务器:"+line);
            bw.newLine();
            bw.flush();
        }
        bw.close();
        ss.close();
    }
}

练习4

  • 客户端的输入来自文本文件
  • 服务器端写入文本文件
public class ClientDemo {
    public static void main(String[] args) throws IOException {
        //创建客户端的Socket
        //Socket s=new Socket(InetAddress.getByName("127.0.0.1"),10000);
        Socket s=new Socket("127.0.0.1",10010);
        //数据来自文本
        BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream("c.txt")));
        //封装输出流对象,用字符流传输
        BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        String line;
        while((line=br.readLine())!=null){
            if("886".equals(line))
                break;
            bw.write(line);
            bw.newLine();
            bw.flush();
        }
        br.close();
        s.close();
    }
}

练习5

  • 客户端:数据来自于文本文件,接收服务器反馈
  • 服务器:接收到的数据写入文本文件,给出反馈
public class ServerDemo {
    public static void main(String[] args) throws IOException {
        ServerSocket ss=new ServerSocket(10010);
        Socket s=ss.accept();
        InputStream is=s.getInputStream();
        InputStreamReader isr=new InputStreamReader(is);
        BufferedReader br=new BufferedReader(isr);
        BufferedWriter bw=new BufferedWriter(new FileWriter("s.txt"));
        String line;
        while((line=br.readLine())!=null){
//            if("886".equals(line)){
//                break;
//            }
            bw.write("服务器:"+line);
            bw.newLine();
            bw.flush();
        }
        //给反馈
        BufferedWriter bwServer=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        bwServer.write("文件上传成功!");
        bwServer.newLine();
        bwServer.flush();
        bw.close();
        ss.close();
    }
}
public class ClientDemo {
    public static void main(String[] args) throws IOException {
        //创建客户端的Socket
        //Socket s=new Socket(InetAddress.getByName("127.0.0.1"),10000);
        Socket s=new Socket("127.0.0.1",10010);
        //数据来自文本
        BufferedReader br=new BufferedReader(new FileReader("c.txt"));
        BufferedReader bbr=new BufferedReader(new InputStreamReader(new FileInputStream("c.txt")));
        //封装输出流对象,用字符流传输
        BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        String line;
        while((line=br.readLine())!=null){
            bw.write(line);
            bw.newLine();
            bw.flush();
        }
//        //自定义结束标记
//        bw.write("886");
//        bw.newLine();
//        bw.flush();
        s.shutdownOutput();
        //接受反馈
        BufferedReader brClient =new BufferedReader(new InputStreamReader(s.getInputStream()));
        String data=brClient.readLine();
        System.out.println("服务器反馈:"+data);
        br.close();
        s.close();
    }
}

出现问题:程序一直等待

  • 原因:读数据的方法是阻塞式的,
  • 解决办法:自定义结束标记;使用shutdownOutput()
  • 练习6

    • 客户端:数据来自于文本文件,接收服务器反馈
    • 服务器:接收到的数据写入文本文件,给出反馈,代码用线程进行封装,为每一个客户端开启一个线程
    public class ServerThread implements Runnable {
        public Socket s;
        public ServerThread(Socket s) {
            this.s=s;
        }
    
        @Override
        public void run() {
            //接收数据,写入文本
            try {
                BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));
                BufferedWriter bw=new BufferedWriter(new FileWriter("src/com/itheima07/s.txt"));
                String line;
                while ((line= br.readLine())!=null){
                    bw.write(line);
                    bw.newLine();
                    bw.flush();
                }
                //给出反馈
                BufferedWriter bwServer=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
                bwServer.write("文件上传成功!");
                bwServer.newLine();
                bwServer.flush();
                s.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
    
    public class ServerDemo {
        public static void main(String[] args) throws IOException {
            //创建服务器端Socket
            ServerSocket serverSocket=new ServerSocket(10010);
            while(true){//监听客户端连接,返回一个Socket对象
                Socket s = serverSocket.accept();
                //为每个客户端开启一个线程
                new Thread(new ServerThread(s)).start();
            }
    
        }
    }
    
    public class ClientDemo {
        public static void main(String[] args) throws IOException {
            //创建客户端的Socket
            Socket s=new Socket("127.0.0.1",10010);
            //数据来自文本
            BufferedReader br=new BufferedReader(new FileReader("c.txt"));
            BufferedReader bbr=new BufferedReader(new InputStreamReader(new FileInputStream("c.txt")));
            //封装输出流对象,用字符流传输
            BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
            String line;
            while((line=br.readLine())!=null){
                bw.write(line);
                bw.newLine();
                bw.flush();
            }
            s.shutdownOutput();
            //接受反馈
            BufferedReader brClient =new BufferedReader(new InputStreamReader(s.getInputStream()));
            String data=brClient.readLine();
            System.out.println("服务器反馈:"+data);
            br.close();
            s.close();
        }
    }
    
更多推荐

ElasticSearch

文章目录一、引言1.1海量数据1.2全文检索二、ES概述2.1ES的介绍2.2ES的由来三、ElasticSearch安装3.1安装ES&Kibana3.2安装IK分词器四、ElasticSearch基本操作4.1ES的结构4.1.1索引Index,分片和备份4.1.2类型Type4.1.3文档Doc4.1.4属性Fi

【Linux学习笔记】 - 常用指令学习及其验证(下)

前言:本文延续上一篇文章【Linux学习笔记】-常用指令学习及其验证(上)对常用的指令进行介绍和验证。一、mv指令(1)功能:用来移动文件或者将文件改名(2)语法及验证:语法:mv[选项][源文件或目录][目标文件或目录]当第二个参数(即目标文件或目录)是不存在的文件或目录时,此时源文件或目录只能有一个,它将被重新命名

MVCC:多版本并发控制案例分析(二)

(笔记总结自b站马士兵教育课程)本文主要分析readview的案例。一、简介readview:表示事务进行快照读操作的时候产生的读视图,在该事务进行快照读的那一刻会生成一个系统当前的快照,但是此时的快照不是数据的快照,而是事务相关信息的快照。trx_listreadview生成时刻当前系统活跃的事务idup_limit

华为认证HCIP知识点

文章目录前言考试内容数据通信领域各场景通用核心知识OSPF知识点IS-IS知识点BGP知识点IGMP知识点ICMP知识点数据通信领域路由交换高阶知识总结前言本博客仅做学习笔记,如有侵权,联系后即刻更改科普:考试内容参考网址HCIP认证主要定位于中小型网络的规划、设计、配置与维护,包含网络基础、常见接口与电缆、以太网交换

数据结构学习笔记—— 排序算法总结【ヾ(≧▽≦*)o所有的排序算法考点看这一篇你就懂啦!!!】

目录一、排序算法总结(一)排序算法分类(二)表格比较二、详细分析(最重要考点!!!)(一)稳定性(二)时间复杂度(三)空间复杂度(四)比较次数(五)平均比较次数(六)排序趟数(七)根据规模选择排序算法(八)每趟确定的元素最终位置(九)存储方式的选择一、排序算法总结常用排序算法如下:#mermaid-svg-nyHNG1

驱动开发概念详解

1、什么是驱动能够驱使硬件实现特定功能的软件代码,可以根据驱动程序是否依赖于系统内核将其分为裸机驱动和系统驱动1.1裸机驱动编写的驱动代码中没有进行任何内核相关的API调用,开发者查询资料配置寄存器完成硬件相关控制,不依赖于系统内核,由开发者独立完成,相对而言比较简单。1.2系统驱动系统驱动指的是编写的驱动代码中需要调

了解JVM

一.了解JVM1.1什么是JVMJVM是JavaVirtualMachine(Java虚拟机)的缩写,是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟计算机功能来实现的,JVM屏蔽了与具体操作系统平台相关的信息,Java程序只需生成在Java虚拟机上运行的字节码,就可以在多种平台上不加修改的运行。JVM在执行字节

PyTorch之张量的相关操作大全 ->(个人学习记录笔记)

文章目录Torch1.张量的创建1.1直接创建1.1.1`torch.tensor`1.1.2`torch.from_numpy(ndarray)`1.2依据数值创建1.2.1`torch.zeros`1.2.2`torch.zeros_like`1.2.3`torch.ones`1.2.4`torch.ones_li

人工智能的未来:从 Jetson 到 GPT,沙龙见闻与洞察

前言在当今数字化时代,人工智能正以惊人的速度改变着我们的生活和工作方式。从智能语音助手到自动驾驶汽车,从智能家居到医疗诊断,人工智能技术已经广泛渗透到各个行业,并为其带来了巨大的变革和创新。越来越多的行业专家、学者和从业者积极参与到人工智能与行业应用实践中,为了进一步推动人工智能的发展和应用。活动介绍本次活动是由Mic

GPT引领前沿与应用突破之GPT4科研实践技术与AI绘图

GPT对于每个科研人员已经成为不可或缺的辅助工具,不同的研究领域和项目具有不同的需求。如在科研编程、绘图领域:1、编程建议和示例代码:无论你使用的编程语言是Python、R、MATLAB还是其他语言,都可以为你提供相关的代码示例。2、数据可视化:生成各种类型的数据可视化图表,如折线图、柱状图、散点图、饼图、热力图等。提

Leetcode.2522 将字符串分割成值不超过 K 的子字符串

题目链接Leetcode.2522将字符串分割成值不超过K的子字符串rating:1605题目描述给你一个字符串sss,它每一位都是111到999之间的数字组成,同时给你一个整数kkk。如果一个字符串sss的分割满足以下条件,我们称它是一个好分割:sss中每个数位恰好属于一个子字符串。每个子字符串的值都小于等于kkk。

热文推荐