网络编程

概述

可以理解为发送信件

计算机网络:

把分布在不同地点且具有独立功能的多个计算机通过通信设备和通信线路连接起来,在功能完善的网络软件运行环境下,以实现资源共享为目标的系统。

网络编程的目的:

无线电台...创博交流信息,数据交换。通信

想要达到这个效果需要什么:
1.如何准确的定位网络上一台主机 192.168.1.1:端口,定位到计算机上面的某个资源
2.找到了这个主机,如何传输数据?
javaweb 网页编程 B/S
网络编程 TCP/IP C/S

网络通信要素

如何实现双方的通信
通信双方的地址:

  • IP
  • 端口号
  • 192.168.1.1:3306

规则:网络通信的协议

小结:
1.网络编程主要有两个问题

  • 如何定位到网络上的一台或多台主机
  • 找到主机之后如何进行通信
    2.网络编程的要素
  • IP和端口号 ip
  • 网络通信协议 udp,tcp
    3.万物皆对象 java

IP

IP地址:InetAddress

  • 唯一定位一台网络上的计算机
  • 127.0.0.1:代表本机 localhost
  • IP地址的分类
    • IPv4 / IPv6

      • IPv4:127.0.0.1 4个字节组成,0 ~255 ,共计42亿
      • IPv6:fe24::93a5:a4d9:9a4b:c5b9%28 ,128位,8个无符号整数
    • 公网 (互联网使用)- 私网(局域网)

      • ABCD类地址
      • 192.168.xx.xx 专门给组织内部使用
    • 域名:记忆IP问题

      • IP:www.vip.com

我们直接上代码展示

package javaSEStudy.network;

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

public class testInetAddress {
    public static void main(String[] args) throws UnknownHostException {
        //查询本机地址
        InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");
        System.out.println(inetAddress1);
        InetAddress inetAddress3 = InetAddress.getByName("localhost");
        System.out.println(inetAddress1);
        InetAddress inetAddress4 = InetAddress.getLocalHost();
        System.out.println(inetAddress1);


        //查询网站IP地址
        InetAddress inetAddress2 = InetAddress.getByName("www.baidu.com");
        System.out.println(inetAddress2);

        //常用方法
        //意义不大,可不管
        System.out.println(inetAddress2.getAddress());
        //获得规范名字
        System.out.println(inetAddress2.getCanonicalHostName());
        //获得IP
        System.out.println(inetAddress2.getHostAddress());
        //获得域名或自己电脑名字
        System.out.println(inetAddress2.getHostName());
    }
}

端口

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

  • 不同的进程有不同的端口号!用来区分软件
  • 被规定为0~65535
  • TCP / UDP 65535 * 2,因此tcp和udp可以分别设置端口80,单个协议下端口号不能冲突
  • 端口分类:
    • 公有端口 0~1023
      • HTTp : 80
      • HTTPS: 443
      • FTP: 21
      • Telent:23
    • 程序注册端口: 1014~49151,分配给用户或者程序
      • Tomcat:8080
      • MYSQL: 3306
      • Oracle:1521
    • 动态,私有端口:49152~66535
netstat -ano  #查看所有端口号
netstat -ano|findstr""  #查看指定的端口
tasklist|findstr"" #查看指定端口的进程  
任务管理器查看

我们直接举个栗子

package javaSEStudy.network;

import java.net.InetSocketAddress;

public class testInetSocketAddress {
    public static void main(String[] args) {
        InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 8080);
        InetSocketAddress inetSocketAddress1 = new InetSocketAddress("localhost", 8080);
        System.out.println(inetSocketAddress);
        System.out.println(inetSocketAddress1);

        System.out.println(inetSocketAddress.getAddress());
        //端口
        System.out.println(inetSocketAddress.getPort());
        //地址
        System.out.println(inetSocketAddress.getHostName());
    }
}

通信协议

协议:约定,相当于普通话
网络通信协议:速率,传输码率,代码结构,传输控制...

大事化小:分层!

TCP/IP协议簇(实际上是一个协议):

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

出名的协议:

  • TCP:用户传输协议
  • IP:网络互联协议

TCP与UDP对比
TCP:打电话

  • 连接稳定
  • 三次握手,四次挥手
最少需要三次这种,才能保证稳定
A:你愁啥
B:瞅你咋地
A:干一场

A:我要走了
B:你真的要走了吗
B:你真的真的要走了吗
A:我真的走了
close
  • 客户端,服务端
  • 传输完成释放连接,效率低

UDP:发短信

  • 不稳定,不连接
  • 客户端,服务端:没有明确的界限
  • 不管有没有准备好,都会发送
  • DDOS:洪水攻击!(大量无意义数据发送,造成端口堵塞,也叫饱和攻击)

TCP实现聊天

客户端:
1.连接服务器Socket
2.发送消息

服务器:
1.建立服务端口ServerSocket
2.等待用户的连接accept
3.接受用户消息

直接上代码:
先创建一个服务端

package javaSEStudy.network.tcp;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
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 baos = null;

        try {
            //1.我得有一个地址
            serverSocket = new ServerSocket(9999);

            while (true) {

                //2.等待客户端连接 
                accept = serverSocket.accept();

                //3.读取客户端消息
                is = accept.getInputStream();

                //管道流
                baos = new ByteArrayOutputStream();
                byte[] buffer = new byte[1024];
                int len;
                while ((len = is.read(buffer)) != -1) {
                    baos.write(buffer, 0, len);
                }
                System.out.println(baos.toString());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //关闭资源
            if (baos != null) {
                try {
                    baos.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();
                }
            }
        }
    }
}

再创建一个客户端

package javaSEStudy.network.tcp;

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

//客户端
public class TcpClientDemo01 {
    public static void main(String[] args) {

        Socket socket = null;
        OutputStream os = null;

        try {
            //1.我得要知道服务器地址 ,端口号
            InetAddress serverIP = InetAddress.getByName("127.0.0.1");
            int port = 9999;

            //2.创建一个socket连接
            socket = new Socket(serverIP,port);

            //3.发送消息 IO流
            os = socket.getOutputStream();
            os.write("hello,欢迎来到网络世界".getBytes());


        } 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();
                }
            }
        }
    }
}

ps:先启动服务端,在启动客户端

文件上传

我们直接来举个栗子
先创建一个服务端

package javaSEStudy.network.tcp.demo02;

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

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

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

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

        //4.文件输出
        FileOutputStream fos = new FileOutputStream(new File("receve.jpg"));
        byte[] buffer = new byte[1024];
        int len;
        while ((len = is.read(buffer)) != -1) {
            fos.write(buffer, 0, len);
        }

        //通知客户端接受完毕
        OutputStream os = accept.getOutputStream();
        os.write("我接受完毕了,你可以断开了".getBytes());

        //关闭资源
        os.flush();
        fos.close();
        is.close();
        accept.close();
        serverSocket.close();

    }
}

再创建一个客户端

package javaSEStudy.network.tcp.demo02;

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

//客户端
public class TcpClientDemo02 {
    public static void main(String[] args) throws IOException {
        //1.创建一个Socket连接
        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000);

        //2.创建一个输出流
        OutputStream os = socket.getOutputStream();

        //3.文件流-->读取文件
        FileInputStream fis = new FileInputStream(new File("D:/IdeaProject/Xie/src/javaSEStudy/network/tcp/view.jpg"));

        //4.写出文件
        byte[] buffer = new byte[1024];
        int len;
        while((len = fis.read(buffer)) != -1){
            os.write(buffer, 0, len);
        }

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

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

        //5.关闭资源
        baos.close();
        is.close();
        os.close();
        fis.close();
        socket.close();
    }
}

Tomcat

服务端:

  • 自定义 S
  • Tomcat服务器 S :Java后台开发

客户端:

  • 自定义 C
  • 浏览器 B

UDP

发短信:不用链接,但是需要对方的地址
我们直接来举个栗子
发送端:

package javaSEStudy.network.udp;

import java.io.IOException;
import java.net.*;

//不需要连接服务器
public class UDPClientDemo01 {
    public static void main(String[] args) throws IOException {
        //1.建立一个socket
        DatagramSocket socket = new DatagramSocket();

        //2.发送的人
        InetAddress localhost = InetAddress.getByName("localhost");
        int port = 9090;

        //3.建个包
        String msg = "Hello World";
        //数据 数据的长度起始 数据长度 发送给谁 端口号
        DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, localhost, port);

        //4.发送包
        socket.send(packet);

        //5.关闭流
        socket.close();
    }
}

接收端

package javaSEStudy.network.udp;

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

//还是要等待客户端的连接
//相当于收快递,没有及时收到也可以
public class UDPServerDemo01 {
    public static void main(String[] args) throws IOException {
        //开放端口
        DatagramSocket socket = new DatagramSocket(9090);

        //接受数据包
        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();
    }
}

UDP聊天发送

发送端:

package javaSEStudy.network.chat.deom01;

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 UDPSenderDemo01 {
    public static void main(String[] args) throws IOException {
        DatagramSocket socket = new DatagramSocket(8888);
        System.out.println("发送端启动,请输入发送内容(回车键发送):");
        System.out.println("输入bye退出聊天程序");

        //准备数据  控制台读取System.in
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        while (true) {
            String data = reader.readLine();
            byte[] datas = data.getBytes(StandardCharsets.UTF_8);

            DatagramPacket packet = new DatagramPacket(datas,0,datas.length,
                                    new InetSocketAddress("localhost",6666));

            socket.send(packet);

            if(data.equals("bye")){
                break;
            }
        }
        socket.close();
    }
}

接收端:

package javaSEStudy.network.chat.deom01;

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

public class UDPReceiveDemo01 {
    public static void main(String[] args) throws IOException {
        System.setProperty("file.encoding", "UTF-8");
        DatagramSocket socket = new DatagramSocket(6666);
        System.out.println("接收端启动,等待数据...");

        try {
            while (true) {
                byte[] container = new byte[1024];
                DatagramPacket packet = new DatagramPacket(container, container.length);
                socket.receive(packet);

                // 使用UTF-8编码并正确处理数据长度
                String receivedData = new String(
                        packet.getData(),
                        0,
                        packet.getLength(),
                        StandardCharsets.UTF_8
                ).trim();

                System.out.println("接收到消息: " + receivedData);

                if ("bye".equalsIgnoreCase(receivedData)) {
                    break;
                }
            }
        } finally {
            System.out.println("退出聊天");
            socket.close();
        }
    }
}

多线程在线聊天

先创建一个发送端

package javaSEStudy.network.chat.demo02;

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.net.SocketException;
import java.nio.charset.StandardCharsets;

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

    private int fromPort;
    private String toIP;
    private int toPort;

    public TalkSend(int fromPort, String toIP, int toPort)  {
        this.fromPort= fromPort;
        this.toIP = toIP;
        this.toPort = toPort;

        try {
             socket = new DatagramSocket(fromPort);
             reader = new BufferedReader(new InputStreamReader(System.in));
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {

        System.out.println("发送端启动,请输入发送内容(回车键发送):");
        System.out.println("输入bye退出聊天程序");

        while (true) {

            try {
                String data = reader.readLine();
                byte[] datas = data.getBytes(StandardCharsets.UTF_8);

                DatagramPacket packet = new DatagramPacket(datas, 0, datas.length,
                                        new InetSocketAddress(this.toIP, this.toPort));

                socket.send(packet);

                if (data.equals("bye")) {
                    break;
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        System.out.println("已退出程序");
        socket.close();
    }
}

再创建一个接收端

package javaSEStudy.network.chat.demo02;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;

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;
        System.setProperty("file.encoding", "UTF-8");
        System.out.println("接收端启动,等待数据...");
        try {
            socket = new DatagramSocket(port);
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        try {
            while (true) {
                byte[] container = new byte[1024];
                DatagramPacket packet = new DatagramPacket(container, container.length);
                try {
                    socket.receive(packet);
                } catch (IOException e) {
                    e.printStackTrace();
                }

                // 使用UTF-8编码并正确处理数据长度
                String receivedData = new String(
                        packet.getData(),
                        0,
                        packet.getLength(),
                        StandardCharsets.UTF_8
                ).trim();

                System.out.println(msgFrom+ ":" + receivedData);

                if ("bye".equalsIgnoreCase(receivedData)) {
                    break;
                }
            }
        } finally {
            System.out.println("退出聊天");
            socket.close();
        }
    }
}

使用多线程,创建学生端口

package javaSEStudy.network.chat.demo02;

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

使用多线程创建老师端口

package javaSEStudy.network.chat.demo02;

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

URl

https://www.baidu.com
URL:统一资源定位符,定位互联网上的某一种资源

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

先来个示范

package javaSEStudy.network.chat.demo03;

import java.net.MalformedURLException;
import java.net.URL;

public class URlDemom {
    public static void main(String[] args) throws MalformedURLException {
        URL url = new URL("https://localhost:8080/hellworld/inddex.jps?username=admin&password=admin");
        //得到协议
        System.out.println(url.getProtocol());
        //主机IP
        System.out.println(url.getHost());
        //端口
        System.out.println(url.getPort());
        //文件地址
        System.out.println(url.getPath());
        //文件全路径
        System.out.println(url.getFile());
        //得到URl查询的名字(带的参数)
        System.out.println(url.getQuery());
    }
}

来个实例,下载壁纸

package javaSEStudy.network.chat.demo03;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class URlDown {
    public static void main(String[] args) throws IOException {
        //下载地址
        URL url = new URL("https://haowallpaper.com/link/common/file/previewFileImg/15942630369381760");

        //连接到这个资源HTTP
        HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
        InputStream is = urlConnection.getInputStream();

        FileOutputStream fos = new FileOutputStream("ww.jpg");

        byte[] buffer = new byte[1024];
        int len;
        while ((len = is.read(buffer)) != -1) {
            fos.write(buffer, 0, len);
        }
        fos.close();
        is.close();
        //断开连接
        urlConnection.disconnect();
    }
}
posted @ 2025-04-08 17:36  sprint077  阅读(15)  评论(0)    收藏  举报