网络编程简单回顾

网络编程

OSI模型

https://img-blog.csdnimg.cn/d8e58a2cf833444985c06bfa33488007.gif#pic_center

网络编程主要针对传输层

主要TCP,UDP,IP协议

IP地址

ip地址:InetAddress

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

  • 127.0.0.1 本机localhost

  • ip地址分类

    ipv4/ipv6

    ip4: 127.0.0.1 四个字节的组成

    ip6:fe80::2a2d:4550:29e5:66ee%14 128位 8个无符号整数

    公网(互联网)-私网(局域网)

    192.168.xx.xx 一般都是局域网

    IP地址由四段组成,每个字段是一个字节,8位,最大值是255,

    IP地址由两部分组成,即网络地址主机地址。网络地址表示其属于互联网的哪一个网络,主机地址表示其属于该网络中的哪一台主机。二者是主从关系。

    IP地址的四大类型标识的是网络中的某台主机。IPv4的地址长度为32位,共4个字节,但实际中我们用点分十进制记法。

    IP地址根据网络号和主机号来分,分为A、B、C三类及特殊地址D、E。 全0和全1的都保留不用。

    A类:(1.0.0.0-126.0.0.0)(默认子网掩码:255.0.0.0或 0xFF000000)第一个字节为网络号,后三个字节为主机号。该类IP地址的最前面为“0”,所以地址的网络号取值于1~126之间。一般用于大型网络。

    B类:(128.0.0.0-191.255.0.0)(默认子网掩码:255.255.0.0或0xFFFF0000)前两个字节为网络号,后两个字节为主机号。该类IP地址的最前面为“10”,所以地址的网络号取值于128~191之间。一般用于中等规模网络。

    C类:(192.0.0.0-223.255.255.0)(子网掩码:255.255.255.0或 0xFFFFFF00)前三个字节为网络号,最后一个字节为主机号。该类IP地址的最前面为“110”,所以地址的网络号取值于192~223之间。一般用于小型网络。

    D类:是多播地址。该类IP地址的最前面为“1110”,所以地址的网络号取值于224~239之间。一般用于多路广播用户[1]

  • 在IP地址3种主要类型里,各保留了3个区域作为私有地址,其地址范围如下: A类地址:10.0.0.0~10.255.255.255 B类地址:172.16.0.0~172.31.255.255 C类地址:192.168.0.0~192.168.255.255

域名:

记忆IP问题!

代码:

package Intel.ip.lesson01;
​
import java.net.InetAddress;
import java.net.UnknownHostException;
​
//测试Ip
public class TestInetAddress {
​
    public static void main(String[] args) {
        try {
            //查询本机地址
            InetAddress byName = InetAddress.getByName("127.0.0.1");
            System.out.println(byName);
            InetAddress byName3 = InetAddress.getByName("localhost");
            System.out.println(byName3);
            InetAddress byName4 = InetAddress.getLocalHost();
            System.out.println(byName4);
​
            //查询网站ip地址
            InetAddress byName2 = InetAddress.getByName("www.baidu.com");
            System.out.println(byName2);
​
            //常用方法
            System.out.println(byName2.getAddress());
            System.out.println(byName2.getCanonicalHostName());//规范的名字
            System.out.println(byName2.getHostAddress());//ip
            System.out.println(byName2.getHostName());//域名,或者自己电脑的名字
​
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }
​
}
​

端口

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

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

  • 被规定0-65535

  • TCP,UDP:65535*2 tcp:80 udp:80 单个协议下的端口不能冲突

  • 端口分类

    • 公有端口: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 Intel.ip.lesson01;
      ​
      import java.net.InetSocketAddress;
      ​
      public class TestInetSocketAddress {
      ​
          public static void main(String[] args) {
              InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1",8080);
              InetSocketAddress inetSocketAddress2 = new InetSocketAddress("localhost",8080);
              System.out.println(inetSocketAddress);
              System.out.println(inetSocketAddress2);
      ​
              System.out.println(inetSocketAddress.getAddress());
              System.out.println(inetSocketAddress.getHostName());
              System.out.println(inetSocketAddress.getPort());//端口
              System.out.println(inetSocketAddress.getAddress());
          }
      ​
      }
      ​
    • 端口映射:

通信协议

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

分层思想

重要:

TCP:用户传输协议

UDP:用户数据报协议

IP:网络互联协议

TCP是典型的可靠传输,而UDP则是不可靠传输

TCP建立连接需要三次握手,断开连接需要四次挥手

三次握手简单解:

客户端发送请求给用户端 客户端状态改变进入 SYN_SENT 发送的信息SYN被标志为1

用户端发送请求给客户端 用户端状态改变进入 SYN_RCVD 状态 用户端发送的请求为: SYN+ACK帧

客户端发送请求给用户端 客户端状态改变进入 ESTABLISHED

四次挥手简单解释

1)主动--》被动 主动方已经没有数据要发送但是还可以接受数据

2)被动---》主动 被动方这时候还可以发送数据给主动方,表示自己已经知道主动方只能接受数据不会在发送数据

3)被动----》主动 当被动方数据发送完成,没有数据要发送给主动方时,发送响应报文给主动方,告诉自己没有数据要发送给你了,被动方状态改变

4)主动----》被动 主动方发送的确认响应报文,自己进入TIME_WAIT状态,等待时间内没有接受到其他报文就证明对方已经正常关闭,自己也最终关闭

详细:

(1)第一次挥手:主动断开方(可以是客户端,也可以是服务器端),向对方发送一个FIN结束请求报文,此报文的FIN位被设置为1,并且正确设置Sequence Number(序列号)和Acknowledgment Number(确认号)。发送完成后,主动断开方进入FIN_WAIT_1状态,这表示主动断开方没有业务数据要发送给对方,准备关闭SOCKET连接了。

(2)第二次挥手:正常情况下,在收到了主动断开方发送的FIN断开请求报文后,被动断开方会发送一个ACK响应报文,报文的Acknowledgment Number(确认号)值为断开请求报文的Sequence Number (序列号)加1,该ACK确认报文的含义是:“我同意你的连接断开请求”。之后,被动断开方就进入了CLOSE-WAIT(关闭等待)状态,TCP协议服务会通知高层的应用进程,对方向本地方向的连接已经关闭,对方已经没有数据要发送了,若本地还要发送数据给对方,对方依然会接受。被动断开方的CLOSE-WAIT(关闭等待)还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。

主动断开方在收到了ACK报文后,由FIN_WAIT_1转换成FIN_WAIT_2状态。

(3)第三次挥手:在发送完成ACK报文后,被动断开方还可以继续完成业务数据的发送,待剩余数据发送完成后,或者CLOSE-WAIT(关闭等待)截止后,被动断开方会向主动断开方发送一个FIN+ACK结束响应报文,表示被动断开方的数据都发送完了,然后,被动断开方进入LAST_ACK状态。

(4)第四次挥手:主动断开方收在到FIN+ACK断开响应报文后,还需要进行最后的确认,向被动断开方发送一个ACK确认报文,然后,自己就进入TIME_WAIT状态,等待超时后最终关闭连接。处于TIME_WAIT状态的主动断开方,在等待完成2MSL的时间后,如果期间没有收到其他报文,则证明对方已正常关闭,主动断开方的连接最终关闭。

被动断开方在收到主动断开方的最后的ACK报文以后,最终关闭了连接,自己啥也不管了。

TCP协议详解 (史上最全)_tcp协议有哪些_chentiebo的博客-CSDN博客^v88^control_2,239^v2^insert_chatgpt&utm_term=%E9%80%9A%E4%BF%A1%E5%8D%8F%E8%AE%AETcp&spm=1018.2226.3001.4187

TCP编程

客户端

1.连接服务器Socket

2.发送信息

package Intel.ip.lesson02;
​
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
​
//客户端
public class TcpClientDemo01 {
​
    public static void main(String[] args) throws IOException {
        Socket socket = null;
        OutputStream os = null;
​
        //1.要知道服务端的地址,和端口号
        try {
            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("欢迎光临".getBytes(StandardCharsets.UTF_8));
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(os!=null){
                os.close();
            }
            if (socket!=null){
                socket.close();
            }
        }
​
    }
​
}
​
​
​

服务端:

1.建立服务的端口ServerSocket

2.等待用户的连接

3.接受用户信息

package Intel.ip.lesson02;
​
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 socket = null;
        InputStream is = null;
        ByteArrayOutputStream baos = null;
        try {
            //1.自己服务端的地址
            serverSocket = new ServerSocket(9999);
            while (true){
                //2.等待客户端连接过来
                socket = serverSocket.accept();
                //3.读取客户端的信息
                is = socket.getInputStream();
            /*
            字符流写法  不推荐  如果是中文超出1024范围会乱码
            byte[] bytes = new byte[1024];
            int len;
            while ((len=is.read(bytes))!=-1){
                String msg = new String(bytes,0,len);
​
            }
            System.out.println(msg);
             */
​
                //管道流
                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 (socket!=null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (serverSocket!=null){
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
​
        }
​
    }
​
}
​

TCP文件上传

服务器端

package Intel.ip.lesson02;
​
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
​
public class TcpServerDemo02 {
​
    public static void main(String[] args) throws IOException {
        //1.创建服务
        ServerSocket serverSocket = new ServerSocket(9000);
        //2.监听客户端的连接
        Socket socket = serverSocket.accept();//阻塞式监听,会一直等待客户端的连接
        //获取输入流
        InputStream is = socket.getInputStream();
​
        //文件输出
        FileOutputStream fos = new FileOutputStream(new File("receive.jpg"));
        byte[] buffer = new byte[1024];
        int len;
        while ((len=is.read(buffer))!=-1){
            fos.write(buffer,0,len);
​
        }
​
        //通知客户端我接受完毕
        OutputStream os = socket.getOutputStream();
        os.write("服务端接受完毕,可以断开".getBytes(StandardCharsets.UTF_8));
​
​
        //关闭资源
        fos.close();
        is.close();
        socket.close();
        serverSocket.close();
​
    }
​
}
​
​
​

客户端

package Intel.ip.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("127.0.0.1"),9000);
        //2.创建一个输出流
        OutputStream os = socket.getOutputStream();
​
        //3.读取文件
        FileInputStream fis = new FileInputStream(new File("E:\\idealearn\\javase\\javaselearn\\src\\1.jpg"));
        //4.写出文件
        byte[] buffer = new byte[1024];
        int len;
        while ((len= fis.read(buffer))!=-1){
            os.write(buffer,0,len);
        }
​
        //通知服务端我已经传输完了
        socket.shutdownOutput();
​
​
        //确定服务器接受完毕,才能断开连接
        InputStream inputStream = socket.getInputStream();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
​
        byte[] buffer2 = new byte[2048];
        int len2;
        while ((len2=inputStream.read(buffer2))!=-1){
            baos.write(buffer2,0,len2);
        }
​
        System.out.println(baos.toString());
​
        //5.关闭资源
        baos.close();
        inputStream.close();
​
        fis.close();
        os.close();
        socket.close();
​
​
    }
​
}
​

Tomcat服务器

UDP

不需要连接

发送端

package Intel.ip.lesson03;
​
import java.net.*;
​
//测试UDP,不需要连接的服务器
public class UpdClientDemo01 {
​
    public static void main(String[] args) throws Exception {
        //1.建立一个Socket
        DatagramSocket socket = new DatagramSocket();
​
        //2.建一个包
        String msg = "你好,服务器";
        InetAddress localhost = InetAddress.getByName("localhost");
        int port = 9090;
​
        //数据  数据长度的起始位置  要发送的对象
        DatagramPacket packet = new DatagramPacket(msg.getBytes(),0,msg.getBytes().length,localhost,port);
​
        //3.发送包
        socket.send(packet);
​
        //关闭流
        socket.close();
    }
​
}
​

接受端

package Intel.ip.lesson03;
​
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
//还是要等待客户端的链接
public class UpdServerDemo01 {
​
    public static void main(String[] args) throws Exception {
        //开放端口
        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();
​
​
​
    }
​
}
​

循环发送信息

发送方:

package Intel.ip.chat;
​
import java.io.BufferedReader;
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 Exception {
​
        DatagramSocket socket = new DatagramSocket(8888);
​
        //准备数据
​
        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 Intel.ip.chat;
​
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[] container = new byte[1024];
            DatagramPacket packet = new DatagramPacket(container,0,container.length);
            socket.receive(packet);//阻塞式接受包裹
​
            //断开连接
            byte[] data = packet.getData();
            String receiveData = new String(data, 0, packet.getLength());
            System.out.println(receiveData);
            if (receiveData.equals("bye")){
                break;
            }
​
​
        }socket.close();
    }
​
}
​

在线咨询,两个人都可以是发送方,也都可以是接受方

代码实例

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

public class TalkSend implements Runnable {

    DatagramSocket socket = null;
    BufferedReader reader = null;

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

    public TalkSend(){

    }

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

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

    }

    @Override
    public void run() {

        //准备数据

        while (true){
            String data = null;
            try {
                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();
            }

        }

        socket.close();
    }
}

package Intel.ip.chat;
​
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
​
public class TalkReceive implements Runnable{
​
    DatagramSocket socket = null;
    int port;
    private String msgFrom;
​
    public TalkReceive(int port,String msgFrom) {
​
        this.port = port;
        this.msgFrom = msgFrom;
        try {
            socket = new DatagramSocket(port);
        } catch (SocketException e) {
            e.printStackTrace();
        }
​
    }
​
    @Override
    public void run() {
​
​
        while (true){
            try {
                //准备接受包裹
                byte[] container = new byte[1024];
                DatagramPacket packet = new DatagramPacket(container,0,container.length);
                socket.receive(packet);//阻塞式接受包裹
​
                //断开连接
                byte[] data = packet.getData();
                String receiveData = new String(data, 0, packet.getLength());
                System.out.println(msgFrom+"说:"+receiveData);
                if (receiveData.equals("bye")){
                    break;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
​
​
        }socket.close();
    }
}
​
package Intel.ip.chat;
​
public class TalkTeacher {
​
    public static void main(String[] args) {
        new Thread(new TalkSend("localhost",8181,5555)).start();
        new Thread(new TalkReceive(9191,"学生")).start();
    }
​
}
​
package Intel.ip.chat;
​
public class TalkStudent {
​
    public static void main(String[] args) {
        new Thread(new TalkSend("localhost",9191,7777)).start();
        new Thread(new TalkReceive(8181,"老师")).start();
    }
​
}
​

URL

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

DNS 域名解析 把域名解析为ip

1协议://ip地址 : 端口/项目名/对应的资源

package Intel.ip.lesson04;
​
import java.net.MalformedURLException;
import java.net.URL;
​
public class URLDemo01 {
​
    public static void main(String[] args) throws MalformedURLException {
        URL url = new URL("http://localhost:8080/helloworld/index.jsp?uesername=song&password=123");
        System.out.println(url.getProtocol());//协议
        System.out.println(url.getHost());//ip
        System.out.println(url.getPort());//端口
        System.out.println(url.getPath());//文件
        System.out.println(url.getFile());//文件全路径
        System.out.println(url.getQuery());//参数
    }
    
}
​

通过url下载资源

package Intel.ip.lesson04;
​
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
​
public class URLDown {
​
    public static void main(String[] args) throws Exception {
//        下载地址
        URL url = new URL("https://m801.music.126.net/20230713185811/d9f47edd78c1018752375ef15390775c/jdyyaac/obj/w5rDlsOJwrLDjj7CmsOj/29234809622/464f/4b97/8bcd/844b58951a613b79ef18cd7c10cb1111.m4a");
​
        //连接到这个资源
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
​
        InputStream inputStream = urlConnection.getInputStream();
​
        FileOutputStream fos = new FileOutputStream("11.m4a");
​
        byte[] buffer = new byte[1024];
        int len;
        while ((len=inputStream.read(buffer))!=-1){
            fos.write(buffer,0,len);
        }
​
        fos.close();
        inputStream.close();
        urlConnection.disconnect();
​
    }
​
}
​
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值