首页 > 编程语言 >Java学习笔记(九)网络编程

Java学习笔记(九)网络编程

时间:2023-03-24 23:11:38浏览次数:56  
标签:java socket 编程 笔记 Java import new net public

网络编程

概述

ppwFqR1.md.png

计算机网络:

计算机网络是将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。

网络编程的目的:

无线电台···传播交流信息,数据交换,通信

想要达到这个效果需要什么:

  1. 如何准确的定位网络上的一台主机: 192.168.xx.xx:端口,定位到这台计算机上的某个资源
  2. 找到了这个主机,如何传输数据:

javaweb:B/S

网络编程:C/S

网络通信的要素

如何实现网络的通信?

  • ip
  • 端口号
  • 192.168.16.124:5900

规则

ppwnZ1H.md.png

小结:

  1. 网络编程中有两个主要的问题
    • 如果准确定位到网络的一台或者多台主机
    • 找到主机之后如何进行通信
  2. 网络编程中的要素
    • IP和端口号 IP
    • 网络通信协议 UDP,TCP
  3. 万物皆对象

IP

ip地址:InetAdress

  • 唯一定位一台网络上计算机

  • 127.0.0.1 : 本机Ip localhost

  • ip地址的分类

    • ip地址的分类
      • IPV4 127.0.0.1 四个字节组成 0-255,42亿,30亿在北美,已用尽
      • IPV6 128位,8个无符号整数
    • 公网(互联网) - 私网(局域网)
      • ABCD类地址
      • 192.168.xx.xx,专门给组织内部使用的
  • 域名

    • IP:www.vip.com
    package com.tyrant.lesson01;
    
    import java.net.InetAddress;
    import java.net.UnknownHostException;
    
    public class InetAddressDemo01 {
        public static void main(String[] args) {
            try {
                //查询网站地址
                InetAddress inetAddress01 = InetAddress.getByName("www.baidu.com");
                System.out.println(inetAddress01);
    
                //查询本机IP
                InetAddress inetAddress02 = InetAddress.getLocalHost();
                System.out.println(inetAddress02);
    
                //常用方法
                System.out.println(inetAddress01.getAddress());//返回地址的字节数组
                System.out.println(inetAddress01.getHostAddress());//返回ip
                System.out.println(inetAddress01.getCanonicalHostName());//规范的名字    IP
                System.out.println(inetAddress01.getHostName());//返回域名
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
        }
    }
    

端口

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

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

  • 被规定0~65535

  • TCP和UDP都有65536个端口,TCP能和UDP端口号能相同,但同一协议下不能使用同一端口

  • 端口分类:

    • 共有端口0~1023
      • HTTP:80
      • HTTPS:443
      • FTP:21
      • Telent:23
    • 程序注册端口:1024~49151,分配用户或者程序
      • Tomcat:8080
      • MySQL:3306
      • Oracle:1521
    • 动态、私有端口:49152~65535
    netstat -ano #查看所有端口
    netstat -ano findstr "5900" # 查看指定的端口
    tasklist|findstr "8696" # 
    
    package com.tyrant.lesson01;
    
    import java.net.InetSocketAddress;
    
    public class inetSocketAddressDemo01 {
        public static void main(String[] args) {
            InetSocketAddress localhost = new InetSocketAddress("localhost", 8080);
            System.out.println(localhost);
            System.out.println(localhost.getAddress());
            System.out.println(localhost.getHostName());
            System.out.println(localhost.getPort());//端口
        }
    }
    

    pp0giJP.md.png

通信协议

协议:约定,就好比我们现在说的都是普通话

网络通信协议:速率,传输码率,代码结构,传输控制

问题:非常复杂

大事化小:分层的概念

TCP/IP协议簇:实际是一组协议

重要:

  • TCP:用户传输协议
  • UDP:用户数据报协议

出名的协议:

  • TCP
  • IP:网络互连协议

TCP UDP对比

TCP:打电话

  • 连接,稳定

  • 三次握手,四次挥手

    连接

    • A:你瞅啥?
    • B:瞅你咋地?
    • 干一场!

    断开

    • A:我要走了
    • B:你真的要走了吗
    • B:你真的真的要走了吗
    • A:我真的要走了
  • 客户端、服务端

  • 传输完成就释放连接,效率低

UDP:发短信

  • 不连接,不稳定
  • 客户端、服务端:没有明确的界限
  • 不管有没有准备好,都可以发给你
  • 导弹
  • DDOS:洪水攻击,(饱和攻击)

TCP

客户端

  1. 连接服务器 Socket
  2. 发送消息
package com.tyrant.lesson02;

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

//客户端
public class TCPClientDemo01 {

    public static void main(String[] args) {

        Socket socket = null;
        OutputStream os = null;

        try {
            //1. 要知道服务器的地址,端口号
            InetAddress ServerIP = InetAddress.getByName("localhost");
            int port = 9999;
            //2. 创建一个socket连接
            socket = new Socket(ServerIP, port);
            //3. 发送消息 IO流
            os = socket.getOutputStream();
            os.write("hello world".getBytes("UTF-8"));

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

服务器

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

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

//服务端
public class TCPServerDemo01 {

    public static void main(String[] args) {

        ServerSocket serverSocket = null;
        Socket accept = null;
        InputStream is = null;
        ByteArrayOutputStream bos = null;

        try {
            //1. 我要有一个地址
            serverSocket = new ServerSocket(9999);
            //2. 等待客户端连过来
            accept = serverSocket.accept();
            //3.读取消息

            //字节缓冲流
            is = accept.getInputStream();

/*
            byte[] bytes = new byte[1024];
            int len;
            while ((len = is.read(bytes)) != -1){
                String s = new String(bytes, 0, len);
                System.out.println(s);
            }
*/

            //管道的概念,使用另一种流去接收
            bos = new ByteArrayOutputStream();
            byte[] bytes = new byte[1024];
            int len;
            while ((len = is.read(bytes)) != -1){
                bos.write(bytes,0,len);
                bos.flush();
            }
            System.out.println(bos.toString());

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

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

文件上传

客户端

age com.tyrant.lesson02;

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

public class TCPClientDemo02 {

    public static void main(String[] args) throws Exception {

        //1. 创建一个socket连接
        Socket socket = new Socket(InetAddress.getByName("localhost"), 8080);
        //2. 创建一个输出流
        OutputStream os = socket.getOutputStream();

        //3. 读文件
        FileInputStream fis = new FileInputStream(new File("src\\com\\tyrant\\lesson02\\keqing001.jpg"));
        byte[] bytes = new byte[1024];
        int len ;
        //4. 写文件
        while ((len = fis.read(bytes)) != -1){
            os.write(bytes,0,len);
        }

        //通知服务器我已经结束了
        socket.shutdownOutput();

        //确定服务器接收完毕,才能断开连接
        InputStream msg = socket.getInputStream();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len2 ;
        while ((len2 = msg.read(buffer)) != -1){
            baos.write(buffer,0,len2);
        }
        System.out.println(baos.toString());


        //释放资源
        baos.close();
        msg.close();
        fis.close();
        os.close();
        socket.close();
    }
}

服务器

package com.tyrant.lesson02;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

public class TCPServerDemo02 {

    public static void main(String[] args) throws Exception {
        //1. 创建服务
        ServerSocket serverSocket = new ServerSocket(8080);

        //2. 监听客户端的连接
        Socket accept = serverSocket.accept();//阻断式监听,会一直等待客户端连接

        //3. 获取输入流
        InputStream is = accept.getInputStream();

        //4. 读文件
        FileOutputStream fos = new FileOutputStream(new File("src\\com\\tyrant\\lesson02\\keqing002.jpg"));
        byte[] bytes = new byte[1024];
        int len;
        while((len = is.read(bytes)) != -1){
            fos.write(bytes,0,len);
        }

        //通知客户端我已接受
        OutputStream msg = accept.getOutputStream();
        msg.write("我已接受".getBytes(StandardCharsets.UTF_8));

        //释放资源
        msg.close();
        fos.close();
        is.close();
        accept.close();
        serverSocket.close();
    }
}

Tomcat

服务端

  • 自定义 S
  • Tomcat服务器 S

客户端

  • 自定义 C
  • 浏览器 B

UDP

发送消息

发短信:不用连接,需要知道对方的地址

发送方

package com.tyrant.lesson03;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.charset.StandardCharsets;

//不需要连接服务器
public class UDPClientDemo01{
    public static void main(String[] args) throws Exception  {

        //1. 建立一个Scoket
        DatagramSocket scoket = new DatagramSocket();

        //2. 建立一个包
        String msg = "Hello World";

        //发送给谁
        InetAddress localhost = InetAddress.getByName("localhost");
        int port = 8080;

        //数据
        DatagramPacket datagramPacket = new DatagramPacket(msg.getBytes(StandardCharsets.UTF_8),0,msg.getBytes(StandardCharsets.UTF_8).length,localhost,port);

        //3. 发送一个包
        scoket.send(datagramPacket);

        //释放资源
        scoket.close();
    }
}

接收方

package com.tyrant.lesson03;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class UDPServerDemo01 {

    //等待客户端的链接
    public static void main(String[] args) throws Exception {
        //开放端口
        DatagramSocket socket = new DatagramSocket(8080);

        //接收数据包
        byte[] buffer = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);

        socket.receive(packet);
        System.out.println(packet.getAddress().getHostAddress());
        System.out.println(new String(packet.getData(),0,packet.getLength()));

        //释放资源
        socket.close();
    }
}

咨询

循环发送

发送方

package com.tyrant.lesson03;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;

public class UDPSenderDemo01 {

    public static void main(String[] args) throws Exception {

        //建立一个Socket连接
        DatagramSocket socket = new DatagramSocket(8888);

        //准备数据
        //从控制台接收
        BufferedReader br  = new BufferedReader(new InputStreamReader(System.in));

        while (true){

            String s = br.readLine();
            byte[] data = s.getBytes(StandardCharsets.UTF_8);
            DatagramPacket packet = new DatagramPacket(data,0,data.length,new InetSocketAddress("localhost",6666));

            //发送数据
            socket.send(packet);

            if (s.equals("bye")){
                break;
            }
        }
        //关闭资源
        br.close();
        socket.close();
    }
}

接收方

package com.tyrant.lesson03;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class UDPReceiveDemo01 {

    public static void main(String[] args) throws Exception {

        //开放端口
        DatagramSocket socket  = new DatagramSocket(6666);
        while (true){

            //接收数据包
            byte[] msg = new byte[1024];
            DatagramPacket packet = new DatagramPacket(msg,0,msg.length);
            socket.receive(packet);
            byte[] data = packet.getData();
            String receiveMsg = new String(data, 0, packet.getLength());
            System.out.println(receiveMsg);
            if (receiveMsg.equals("bye")){
                break;
            }

            //发送数据包
            //socket.send(packet);
        }


        //释放资源
        socket.close();
    }
}

对话

发送类

package com.tyrant.chat;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;

public class TalkSend implements Runnable{
    DatagramSocket socket = null;
    BufferedReader br = null;

    //private String fromIP;
    private int fromPort;
    private String toIP;
    private int toPort;

    public TalkSend( int fromPort, String toIP, int toPort) {
        //this.fromIP = fromIP;
        this.fromPort = fromPort;
        this.toIP = toIP;
        this.toPort = toPort;
        try{
            socket = new DatagramSocket(this.fromPort);
            br  = new BufferedReader(new InputStreamReader(System.in));
        } catch (Exception e){
            e.printStackTrace();
        }
    }

    @Override
    public void run() {

        //准备数据
        //从控制台接收
        try {

            while (true){

                String s = br.readLine();
                byte[] data = s.getBytes(StandardCharsets.UTF_8);
                DatagramPacket packet = new DatagramPacket(data,0,data.length,new InetSocketAddress(this.toIP,this.toPort));

                //发送数据
                socket.send(packet);

                if (s.equals("bye")){
                    break;
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (br != null){
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null){
                socket.close();
            }
        }
    }
}

接收类

package com.tyrant.chat;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class TalkReceive implements Runnable {

    DatagramSocket socket = null;
    private int port;
    private String msgFrom;

    public TalkReceive(int port, String msgFrom) {
        this.port = port;
        this.msgFrom = msgFrom;
        try {
            socket  = new DatagramSocket(this.port);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        //开放端口

        try {
            while (true){

                //接收数据包
                byte[] msg = new byte[1024];
                DatagramPacket packet = new DatagramPacket(msg,0,msg.length);

                //阻塞式接收
                socket.receive(packet);

                byte[] data = packet.getData();
                String receiveMsg = new String(data, 0, packet.getLength());
                System.out.println(msgFrom + ":" + receiveMsg);

                //断开连接
                if (receiveMsg.equals("bye")){
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //释放资源
            socket.close();
        }
    }
}

测试类

package com.tyrant.chat;

public class Student {
    public static void main(String[] args) {
        //开启两个线程
        new Thread(new TalkSend(8888,"localhost",9999)).start();
        new Thread(new TalkReceive(7777,"老师")).start();
    }
}
package com.tyrant.chat;

public class Teacher {
    public static void main(String[] args) {
        //开启两个线程
        new Thread(new TalkSend(6666,"localhost",7777)).start();
        new Thread(new TalkReceive(9999,"学生")).start();
    }
}

URL

https://www.baidu.com/

统一资源定位符:定位资源的,定位互联网上某一个资源

DNS 域名解析

协议://ip地址:端口/项目名/资源

package com.tyrant.lesson04;

import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;

public class URLDemo01 {
    public static void main(String[] args) throws IOException {

        //下载地址
        URL url = new URL("https://i0.hdslb.com/bfs/activity-plat/static/20211216/df3e2ff90b315fca2f8d24a29cb68a47/tFsbCWMDtV.gif");
        System.out.println("协议:" + url.getProtocol());//协议
        System.out.println("主机IP:" + url.getHost());//主机IP
        System.out.println("端口:" + url.getPort());//端口
        System.out.println("文件:" + url.getPath());//文件
        System.out.println("全路径:" + url.getFile());//全路径
        System.out.println("参数:" + url.getQuery());//参数

        //保存到本地
        HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
        InputStream is = urlConnection.getInputStream();
        FileOutputStream fos = new FileOutputStream(new File("xx.gif"));
        byte[] bytes = new byte[1024];
        int len ;
        while ((len = is.read(bytes)) != -1){
            fos.write(bytes,0,len);
        }

        //释放资源
        fos.close();
        is.close();
        urlConnection.disconnect();
    }
}

标签:java,socket,编程,笔记,Java,import,new,net,public
From: https://www.cnblogs.com/tyrantblue/p/17253619.html

相关文章

  • JAVAWEB-北京地铁查询系统(Servlet+JSP+CSS+SQL 实现)
    Servlet+JSP+CSS+SQL实现完善的地铁系统页面#这是我和伙伴合作完成的练习项目#代码我将放在下一篇博客功能介绍:1.地铁线路查询:选择线路,输出线路上的站点名。2.地铁站......
  • java学习日记20230325-抽象类
    抽象类:当父类的某些方法需要声明,但是又不确定如何实现时,可以将其声明为抽象方法,那么这个类就是抽象类!所谓抽象方法,就是没有实现的方法;当一个类中存在抽象方法时,需要将......
  • Java面试-基础篇(一)6
    synchronized与ReentrantLock的区别说到synchronized与ReentrantLock,我们都知道,他们是java并发编程很重要的技术。他们可以帮助我们保证编程过程中数据的正确性,也就是我们......
  • 编写一个方法,计算给定两个数组之和---Java
    要求返回的数组是两个惨呼数组对应元素之和,不对应的元素直接赋给相应的位置packagepractice.people.apple;/**//编写一个计算给定的两数组之和**/publicclassS......
  • go 笔记 init函数
    来自:goinit函数1、golang里的main函数是程序的入口函数,olang还有另外一个特殊的函数init函数,先于main函数执行init函数的主要作用:初始化不能采用初始化表达式初始化的......
  • Django笔记七之ManyToMany和OneToOne介绍
    ManyToMany是一种多对多的关系,在用途和使用方法上和外键ForeignKey类似。以下是本篇笔记的目录:ManyToMany的介绍through参数through_fields参数ManyToMany关系......
  • java学习日记20230324-final关键字
    final可以修饰类,方法,属性和局部变量当不希望类被继承时,用final修饰类当不希望父类某个方法被子类重写时,使用final当不希望某个属性值被修改时当不希望某个局部变量被......
  • JavaScript数值计算时精度问题处理
    js精度问题当使用JavaScript进行数值计算时,会面临一些精度问题,这些问题可能会导致不正确的结果。以下是一些常见的奇奇怪怪的js数据精度问题:1.浮点数精度问题在JS......
  • stream流笔记
    stream流笔记map转换元素List<Long>ids=list.stream().map(DictionaryMetaPO::getId).collect(Collectors.toList());Collectors.joining拼接字符串Strings=l......
  • [学习笔记] 树链剖分
    树链剖分的用处使用树剖将整棵树剖分为若干条链,组成线性结构,可以方便用其他的数据结构维护信息。一些定义重儿子:该节点的所有子节点中子树大小最大的点。轻儿子:该节点......