IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> Java 网络多线程 -> 正文阅读

[网络协议]Java 网络多线程

IP地址

  1. ip地址:唯一标识主机
  2. ip表示:对于IPV4 4个字节(32位表示)一个字节8位,1个字节0-255
  3. ip地址的组成=网络地址+主机地址
    比如:192.168.16.69
    182.168.16 为网络地址
    69为主机地址
  4. ipv6是互联网工程任务组设计的用于替代ipv4的下一代协议,其地址数量可以为全世界的每一粒沙子编上一个地址,ipv6使用128位表示地址,16个字节,是ipv4的四倍

域名和端口号

域名

  1. www.baidu.com
  2. 好处:方便记忆,解决了记IP的困难
  3. 概念:将IP地址映射成域名

端口号

  1. 概念:用于标识计算机上某个特定的网络程序
  2. 表示形式:0-65535 [0,2^16-1]
  3. 0-1024 已经被占用 在网络开发中不要使用0-1024的端口
  4. 常见的网络程序端口号:tomact:8080 mysql:3306 oracle:1521 sqlserver:1433
    在这里插入图片描述

TCP和UDP

TCP协议:传输控制协议

  1. 使用TCP协议前,须先建立TCP连接,形成数据传输通道
  2. 传输前,采用"三次握手"的方式,是可靠的
  3. TCP协议进行通信的两个应用程序:客户端和服务器
  4. 在连接中可以进行大量的数据传输
  5. 传输完毕,需要释放已经建立的连接,效率低

三次握手:
在这里插入图片描述
UDP协议:用户数据协议

  1. 将数据,源,目的封装成数据包,不需要建立连接
  2. 每个数据包的大小限制在64K内,不适合传输大量的数据
  3. 因无需连接,故是不可靠的
  4. 发送数据结束时无需释放资源(因为不是面向连接的),速度快

InetAddress

  1. 获取本机的InetAddress对象 getLocalHost
  2. 根据指定主机名/域名获取ip地址对象 getByName
  3. 获取InetAddress对象的主机名 getHostName
  4. 获取InetAddress对象的地址 getHostAddress
package JavaStudy;

import java.net.InetAddress;
import java.net.UnknownHostException;

public class API_ {
    public static void main(String[] args) throws UnknownHostException {
        //1.获取本机的InetAddress对象
        InetAddress localHost=InetAddress.getLocalHost();
        System.out.println(localHost);//DESKTOP-1BPR8C4/192.168.10.102

        //2.根据指定的主机名,获取InetAddress对象
        InetAddress host1=InetAddress.getByName("DESKTOP-1BPR8C4");//host1=DESKTOP-1BPR8C4/192.168.10.102
        System.out.println("host1="+host1);

        //3.根据域名返回 InetAddress对象  比如www.baidu.com对应的
        InetAddress host2= InetAddress.getByName("www.baidu.com");
        System.out.println("host2="+host2);//host2=www.baidu.com/36.152.44.96  域名+IP

        //4.通过InetAdress对象获取对应的地址
        String hostAddress=host2.getHostAddress();
        System.out.println("host2 对应的ip=" +hostAddress);//host2 对应的ip=36.152.44.95

        //5.通过 InetAddress对象,获取对应的主机名/或者域名
        String hostName=host2.getHostName();
        System.out.println("host2对应的主机名/域名="+hostName);//www.baidu.com
    }
}

获取本机的信息(主机名/ip)
通过域名获取远程服务器的ip

Socket

  1. 基于客户端–服务端额网络通信
  2. 底层使用的是TCP/IP协议
  3. 应用场景举例:客户端发送数据,服务端接收并显示
    在这里插入图片描述
    把数据写入通道:socket.getOutputStream()
    把数据从通道中读出:socket.getInputStream()

TCP字节流编程

需求:
编写一个服务器端和一个客户端,服务器端在9999端口监听,客户端连接到服务器端,发送
“hello server” 并接受服务器端回发的"hello,client" 再退出
服务器端接收到客户端发送的信息 输出并发送"hello,client" 再退出

  1. 服务端在本机的9999端口监听,等待连接,在没有客户端连接9999端口时,程序会阻塞,等待连接
  2. 客户端连接服务端(ip,端口)
  3. 客户端连接上后,生成socket,通过socket.getOutputStream(),通过输出流写入到数据通道
  4. 设置写入结束标记,socket.shutdoenOutput()
  5. 服务端通过Socket.getInputStream()读取客户端写入到数据通道的数据,显示
  6. 关闭socket和io…
  7. 服务端再通过socket.getOutputStream()写入到数据通道
  8. 设置写入结束标记,socket.shutdoenOutput()
  9. 客户端再通过Socket.getInputStream()读取客户端写入到数据通道的数据,显示
  10. 关闭socket和io…

服务器:

package JavaStudy;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketTCP01Server {
    public static void main(String[] args) throws IOException {
        //1.在本机的9999端口监听,等待连接
        //要求本机没有其他的服务监听9999
        //ServerSocket 可以通过accept()返回多个Socket[多个客户端连接服务器并发)
        ServerSocket serverSocket=new ServerSocket(9999);
        //2.当没有客户端连接9999端口时,程序会阻塞,等待连接
        //如果在客户端连接,则会返回Socket对象,程序继续
        Socket socket=serverSocket.accept();
        //3.通过socket.getInputStram()读取客户端写入数据通道的数据,显示
        InputStream inputStream=socket.getInputStream();
        //4.IO读取
        byte[] buf=new byte[1024];
        int readLen=0;
        while((readLen=inputStream.read(buf))!=-1)
        {
            System.out.println(new String(buf,0,readLen));
        }
        OutputStream outputStream=socket.getOutputStream();
        outputStream.write("hello,client".getBytes());
        socket.shutdownOutput();
        //5.关闭socket
        inputStream.close();
        outputStream.close();
        serverSocket.close();
        socket.close();
    }
}

客户端:

package JavaStudy;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

public class SocketTCP01Client {
    public static void main(String[] args) throws IOException {
        //1.连接服务器(ip,端口)
        //连接本机的9999端口,如果连接成功,返回socket对象
       Socket socket= new Socket(InetAddress.getLocalHost(),9999);
        //2.连接上后,通过socket.getOutStream.得到和socket对象关联的输出流对象
        OutputStream outputStream=socket.getOutputStream();
        //3.通过输出流,写入到数据通道
        outputStream.write("hello server".getBytes());
        //设置一个结束标记
        socket.shutdownOutput();
        //4。关闭流对象和socket,必须关闭

        InputStream inputStream=socket.getInputStream();
        byte[] buf=new byte[1024];
        int len=0;
        while((len=inputStream.read(buf))!=-1)
        {
            System.out.println(new String(buf,0,len));
        }
        outputStream.close();
        inputStream.close();
        socket.close();
        System.out.println("客户端退出");
    }

}

TCP字符流编程

与字节流一样的需求
这里需要采用转换流将字节输入流和字节输出流分别转换为字符输入流和字符输出流
服务端:

package JavaStudy;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketTCP01Server {
    public static void main(String[] args) throws IOException {
        //1.在本机的9999端口监听,等待连接
        //要求本机没有其他的服务监听9999
        //ServerSocket 可以通过accept()返回多个Socket[多个客户端连接服务器并发)
        ServerSocket serverSocket=new ServerSocket(9999);
        //2.当没有客户端连接9999端口时,程序会阻塞,等待连接
        //如果在客户端连接,则会返回Socket对象,程序继续
        Socket socket=serverSocket.accept();
        //3.通过socket.getInputStram()读取客户端写入数据通道的数据,显示
        InputStream inputStream=socket.getInputStream();
        //4.IO读取 使用了转换流,用InputStream将inputStream转换成了字符流
        BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));
        String s=bufferedReader.readLine();
        System.out.println(s);
        OutputStream outputStream=socket.getOutputStream();
        BufferedWriter bufferedWriter=new BufferedWriter(new OutputStreamWriter(outputStream));
        bufferedWriter.write("hello client 字符流");
        bufferedWriter.newLine();
        bufferedWriter.flush();//注意需要手动刷新
        //5.关闭socket
        bufferedReader.close();
        bufferedWriter.close();
        serverSocket.close();
        socket.close();
    }
}

客户端:

package JavaStudy;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

public class SocketTCP01Client {
    public static void main(String[] args) throws IOException {
        //1.连接服务器(ip,端口)
        //连接本机的9999端口,如果连接成功,返回socket对象
       Socket socket= new Socket(InetAddress.getLocalHost(),9999);
        //2.连接上后,通过socket.getOutStream.得到和socket对象关联的输出流对象
        OutputStream outputStream=socket.getOutputStream();
        //3.通过输出流,写入到数据通道,使用字符流
       BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
       bufferedWriter.write("hello server 字符流");
       bufferedWriter.newLine();//插入一个换行符,表示写入的内容介绍,要求对方使用readLine()读!!!
       bufferedWriter.flush();//如果使用字符流,需要手动刷新,斗则数据不会写入通道
        //设置一个结束标记
        socket.shutdownOutput();

        InputStream inputStream=socket.getInputStream();
        BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));
       String s= bufferedReader.readLine();
        System.out.println(s);
        bufferedReader.close();
        bufferedWriter.close();
        socket.close();
        System.out.println("客户端退出");
    }

}

网络文件上传

TCP通信的文件上传控制
原理:客户端读取本地的文件,把文件上传到服务器,服务器再把上传的文件保存到服务器的硬盘上
基本步骤:

  1. 客户端使用本地的字节输入流,读取需要上传的文件
  2. 客户端使用网络网络字节输出流,把读取的文件上传到服务器
  3. 服务器使用网络字节输入流,读取客户端上传的文件
  4. 服务器使用本地字节输出流,把读取到的文件,保存到服务器的硬盘上
  5. 服务器使用网络字节输出流,给客户端写一个"上传成功"
  6. 客户端使用网络字节输入流,读取服务器返回写的数据

注意:
客户端和服务器和本地硬盘进行读写,需要使用自己创建的字节流对象(本地流)
客户端和服务器之间进行读写,必须使用Socket中字节流对象(网络流)

服务器:

package JavaStudy;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    /*
    1.创建一个服务器ServerSocket对象,和系统要指定的端口
    2.使用ServerSocket对象中的方法accept,获取到请求的客户端Socket对象
    3.使用Socket对象中的方法getInputStream获取到网络字节输入流InputStream对象
    4.判断要写入的文件夹是否存在,不存在创建一个
    5.创建一个本地字节输出流FileOutputStream对象,构造方法中绑定其输出的目的地
    6.使用网络字节输入流InputStream中的read读取客户端传入的文件
    7.使用本地字节输出流FileOutoutStream中的write把读取的文件保存到服务器的磁盘上
    8.使用Socket对象中的方法getOutputStream,获取OutputStream对象
    9.使用网络字节输出流OutputStream中的方法write,给客户端写上传成功
    10.释放资源(FileOutputStream,socket,ServerSocket)
     */
    public static void main(String[] args) throws IOException {
        //1.创建一个服务器ServerSocket对象,和系统要指定的端口
       ServerSocket server=new ServerSocket(8888);
       // 2.使用ServerSocket对象中的方法accept,获取到请求的客户端Socket对象
        Socket socket=server.accept();
        //3.使用Socket对象中的方法getInputStream获取到网络字节输入流InputStream对象
        InputStream is=socket.getInputStream();
        //4.判断要写入的文件夹是否存在,不存在创建一个
        File file=new File("d:\\upload");
        if(!file.exists())
        {
            file.mkdirs();
        }
        //5.创建一个本地字节输出流FileOutputStream对象,构造方法中绑定其输出的目的地
        FileOutputStream fos=new FileOutputStream(file+"\\1.jpg");
        int len=0;
        byte[] bytes=new byte[1024];
        while((len=is.read(bytes))!=-1)
        {
           fos.write(bytes,0,len);
        }
        socket.getOutputStream().write("上传成功".getBytes());
        fos.close();
        server.close();
        socket.close();
    }
}

客户端:

package JavaStudy;

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

public class Client {
    public static void main(String[] args) throws IOException {
       //1.创建一个本地字节输入流FileInputStream对象,构造方法中绑定要读取的数据源
        FileInputStream fis=new FileInputStream("D:\\image\\bg2.jpg");
        // 2.创建一个客户端Socket对象,构造方法中绑定服务器的ip地址和端口号
        Socket socket=new Socket(InetAddress.getLocalHost(),8888);
        //3.使用Socket中的方法获取网络字节输出流
        OutputStream os=socket.getOutputStream();
        //4.使用本地字节输入流FilrInputStream对象中的方法读取本地文件
        int len=0;
        //5.使用网络字节输出流OutputStream对象中的方法write,把读取到的文件上传到服务器
        byte[] bytes=new byte[1024];
        while((len=fis.read(bytes))!=-1)
        {
            os.write(bytes,0,len);
        }
        socket.shutdownOutput();//结束输出流
        //6.使用Socket中的方法getInputStream,获取网络字节输入流InputStream对象
        InputStream is=socket.getInputStream();
        //7.使用网络字节输出流InputStream对象中的方法read读取服务器写的数据
        while((len=is.read(bytes))!=-1)
        {
            System.out.println(new String(bytes,0,len));
        }
        //8.释放资源
        fis.close();
        socket.close();
    }
}

文件上传优化分析

可自定义一个文件的命名规则:防止同名的文件覆盖
规则:域名+毫秒值+随机数

  String filename="itcast"+System.currentTimeMillis()+new Random(999999)+"jpg";
 FileOutputStream fos=new FileOutputStream(file+"\\filename");

可以让服务器一直处于监听状态,死循环accept方法,有一个客户端上传文件,就保存一个文件,但这样效率比较低下,所以我们可以采用多线程来提高效率
有一个客户端上传文件,就开启一个线程,完成文件的上传
服务器:

package JavaStudy;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;

public class Server {
    /*
    1.创建一个服务器ServerSocket对象,和系统要指定的端口
    2.使用ServerSocket对象中的方法accept,获取到请求的客户端Socket对象
    3.使用Socket对象中的方法getInputStream获取到网络字节输入流InputStream对象
    4.判断要写入的文件夹是否存在,不存在创建一个
    5.创建一个本地字节输出流FileOutputStream对象,构造方法中绑定其输出的目的地
    6.使用网络字节输入流InputStream中的read读取客户端传入的文件
    7.使用本地字节输出流FileOutoutStream中的write把读取的文件保存到服务器的磁盘上
    8.使用Socket对象中的方法getOutputStream,获取OutputStream对象
    9.使用网络字节输出流OutputStream中的方法write,给客户端写上传成功
    10.释放资源(FileOutputStream,socket,ServerSocket)
     */
    public static void main(String[] args) throws IOException {
        //1.创建一个服务器ServerSocket对象,和系统要指定的端口
       ServerSocket server=new ServerSocket(8888);
       while(true){
       // 2.使用ServerSocket对象中的方法accept,获取到请求的客户端Socket对象
        Socket socket=server.accept();
           new Thread(new java.lang.Runnable() {
            @Override
            public void run() {
                try{
                    //3.使用Socket对象中的方法getInputStream获取到网络字节输入流InputStream对象
                    InputStream is=socket.getInputStream();
                    //4.判断要写入的文件夹是否存在,不存在创建一个

                    File file=new File("d:\\upload");
                    if(!file.exists())
                    {
                        file.mkdirs();
                    }
                    //5.创建一个本地字节输出流FileOutputStream对象,构造方法中绑定其输出的目的地
                    String filename="itcast"+System.currentTimeMillis()+new Random(999999)+".jpg";
                    FileOutputStream fos=new FileOutputStream(file+"\\"+filename);
                    int len=0;
                    byte[] bytes=new byte[1024];
                    while((len=is.read(bytes))!=-1)
                    {
                        fos.write(bytes,0,len);
                    }
                    socket.getOutputStream().write("上传成功".getBytes());
                    fos.close();
                    socket.close();
                }
                catch(IOException e)
                {
                    System.out.println(e);
                }
            }
        }).start();
        }
    }
}

nestat指令

  1. nestat-an 可以查看当前主机网络情况,包括端口监听情况和网络连接情况
  2. nestat-an|more 可以分页显示
  3. 要求在dos控制台下执行win+r
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-09-12 13:30:30  更:2021-09-12 13:30:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年6日历 -2024/6/27 1:41:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码