Java学习15 网络编程 端口 IO流 TCP

网络编程

端口

  • 端口表示不同计算机上的一个程序进程

  • 不同的进程有不同的端口号 用来区分软件

  • 被规定0~65535

  • TCP , UDP : 65536 *2 单个协议下,端口号不能冲突

  • 端口分类:

    • 公有端口: 1~1023
    • HTTP: 80
    • HTTPS: 443
    • FTP : 21
    • Telnet: 23
  • 程序注册端口: 1014 ~49151 分配给用户和程序

    • Tomcat: 8080
    • MySQL : 3306
    • Oracle:1521
  • 动态 私有端口: 49152~65535

netstat -ano | findstr [port]
tasklist | find [port]

io流

Java的IO模型使用Decorator(装饰者)模式 按功能划分Stream 可以动态装配这些Stream 以便获得需要的功能

例如需要一个具有缓冲的文件输入流 则应当组合使用FileInputStream 和 BufferedInputStream

分类

  1. 按处理数据单位不同分为字节流 字符流

    • 1字符 = 2字节 1字节(byte) = 8位(bit) 一个汉子占两个字节长度
    • 字节流:每次读取(写出)一个字节 当传输的资源文件有中文时, 就会出现乱码
    • 字符流:每次读取(写出)两个字节 当有中文时,使用该流就可以正确传输显示中文
  2. 按功能不同分为节点流*处理流

    • 节点流:以从或向一个特定的地方(节点)读写数据 如: FileInputStream
    • 处理流:是对一个已存在的流的连接和封装 通过所封装的流的功能调用实现数据读写 如:BufferedReader 处理流的构造方法总是要带一个其他的流对象做参数. 一个流对象经过其他流的多次包装
  3. 4个基本的抽象流类型 所有的流都继承这4个

输入流输出流
字节流InputStreamoutputStream
字符流ReaderWriter

IO流特性

  • 先进先出 最先写入输出流的数据最先被输入流读取到
  • 顺序存取 可以一个接一个地往流中写入一串字节,读出时也将按写入顺序读取一串字节,不能随即访问中间的数据
  • 只读或只写 每个流只能是输入流或输出流的一种 不能同时具备两个功能 输入流只能进行读操作,对输出流只能进行写操作在一个数据传输通道中,如果既要写入数据 又要读取数据,则要分别提供两个流

IO流常用到的五类一接口

  1. 5个类:File OutputStream InputStream Write Reader,一个接口Serializable
  2. 输入字节流InputStream
    • ByteArrayInputStream:字节数组输入流, 该类的功能就是从字节(Byte[])中进行以字节为单位的读取,也就是将资源文件都以字节的形式存入到该类中的字节数组中去
    • PipeInputStream:管道字节输入流 与PipeOutputStream一起使用,能够实现多线程间的管道通信
    • FileInputStream:装饰者模式中处于装饰者,具体的装饰者都要继承它,所以在该类的子类下都是用来装饰别的流,也就是处理类,
    • BufferedInputStream:缓冲流 对处理流进行装饰 增强,内部会有一个缓存区 用来存放字节 每次都是将缓存区存满然后发送,而不是一个字节或两个字节发送 效率更高
    • DataInputStream:数据输入流 它用来装饰其他输入流 “允许应用程序以与及其无关方式从底层输入流中读取最基本的Java数据类型”
    • FileInputStream:文件输入流 对文件进行读取操作
    • File: 对指定目录进行操作
    • ObjectInputStream:对象输入流 用来提供对"基本数据或对象"的处理存储

字节流和字符流使用情况

  1. 字符流和字节流使用范围:字节流一般用来处理图像 视频 以及ppt Word类型文件 字符流一般用于处理纯文本类型文件 如TXT文件等 字节流可以用来处理纯文本文件 但字符流不能用于处理图像视频等非文本类型文件
  2. InputStreamReader: 字节到字符的桥梁 将字节流以字符流输入
  3. OutputStreamWriter:字符到字节的桥梁 将字节流以字符流输出
  4. 字节流没有缓冲区,是直接输出的 而字符流是输出到缓冲区的, 因此在输出时 字节流不调用close()方法时,信息已经输出了 而字符流只有在调用close()方法关闭缓冲区时,信息才输出.要想字符流在未关闭时输出信息,则需要手动调用flush()方法

TCP

  • 客户端

    1. 连接服务器Socket
    2. 发送消息
  • 服务器

    1. 建立服务的端口ServerSocket
    2. 等待用户的链接accept
    3. 接收用户的消息
package com.wu.network;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

//客户端
public class TCPClient {
    public static void main(String[] args) {
        Socket socket =null;
        OutputStream os =null;

    //知道用户地址
        try {
            InetAddress serverIp = InetAddress.getByName("localhost");
            //端口号
            int port =9999;
            //创建一个socket连接
            socket = new Socket(serverIp,port);
            //发送消息IO流''
            os = socket.getOutputStream();
            os.write("你好,连接测试".getBytes());



        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(socket != null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if(os != null){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

    }
}

package com.wu.network;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

//服务端
public class TCPSever {
    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        Socket socket =null;
        InputStream is = null;
        ByteArrayOutputStream bios=null;


        //新建地址
        try {
             serverSocket = new ServerSocket(9999);
            //等待客户端连接过来
            socket = serverSocket.accept();
            //读取客户端的消息
             is = socket.getInputStream();
            //管道流
            bios = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            while((len= is.read(buffer)) != -1){
                bios.write(buffer,0,len);
            }
            System.out.println(bios.toString());

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //关闭资源
            if(bios != null){
                try {
                    bios.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if(is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if(socket != null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if(serverSocket != null){
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值