网络编程

网络编程

解决单元测试的时候控制台不可以输入的问题:

1.找到idea安装目录bin下的idea.exe.vmoptions和idea64.exe.vmoptions
2.在这两个文件最后加入一行 -Deditable.java.test.console=true 就ok了

计算机网络:

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

javaweb编程是B/S架构

java网络编程是C/S架构

计算机网络的两个核心要素

IP+端口号

IP地址:java类 InetAddress

特殊的ip:127.0.0.1 本机(localhost)

分类:

1、 IP地址分类(IPV4 IPV6)

IPV4:由四个字节组成(32位),大概有42亿 其中30亿在北美,亚洲只有四亿

IPV6: 128位(十六个字节)

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

192.168.0.0到192.168.255.255 比较大的私网,给专门的机构使用

ABCD类地址:

域名:方便对ip的记忆,其实就是ip地址的另一种表现形式

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

public class FileUtilsTest {
    public static void main(String[] args)  {
        try {
            //InetAddress实例化方法(构造器私有化了,不可以通过构造器进行实例化)
            InetAddress inetAddress1=InetAddress.getByName("www.bilibili.com");
            InetAddress inetAddress2=InetAddress.getByName("112.45.120.2");
            InetAddress inetAddress3=InetAddress.getLocalHost();
            //一般情况下输出inetAddress1会慢一点,因为要解析这个域名,并且一般是通过DNS服务器进行解析
            System.out.println(inetAddress1);
            System.out.println(inetAddress2);
            System.out.println(inetAddress3);

            //常用方法
            System.out.println(inetAddress1.getHostName());//获取主机名或者域名
            System.out.println(inetAddress1.getHostAddress());//获取主机ip
            System.out.println(inetAddress1.getCanonicalHostName());//获取规范化的主机名或者ip
            System.out.println(inetAddress3.getCanonicalHostName());
            System.out.println(inetAddress2.getCanonicalHostName());
        }catch (UnknownHostException e){
            e.printStackTrace();
        }

    }

}

端口:每一个端口都对应着一个进程

被规定为0-65535

公认端口(0~1023):

​ HTTP:80

​ HTTPS:43

​ FTP:21

​ Telent:23

注册端口:1024-49151

​ Tomcat:8080

​ Mysql:3306

​ Oracle:1521

动态、私有:19152-65535
 Netstat -ano//查看所有端口

 Netstat -ano|findstr  “要查询的端口”   |:过滤符号

Tasklist|findstr “要查询的端口”   查看进程名

端口号和ip组合得出一个网络套接字:Socket

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

public class FileUtilsTest {
    public static void main(String[] args)  {
        InetSocketAddress inetSocketAddress1=new InetSocketAddress("127.0.0.1",8080);
        InetSocketAddress inetSocketAddress2=new InetSocketAddress("localhost",8080);
        System.out.println(inetSocketAddress1.getAddress());//ip地址
        System.out.println(inetSocketAddress1.getPort());//端口号
        System.out.println(inetSocketAddress1.getHostName());//主机名或者域名
    }

}

C:\Windows\System32\drivers\etc\hosts文件是本机的域名解析文件,当浏览器访问域名的时候,先在这个文件中查找ip,如果找不到再去DNS服务器进行解析。

网络通信协议(对速率、传输代码、代码结构、传输控制步骤、出错控制等制定的标准)

​ OSI参考模型:过于理想化,未能在因特网上广泛推广

​ TCP/IP参考模型:事实上的国际标准

image-20211003144519248

​ 不可以隔层通信。

​ TCP:传输控制协议

​ UDP:用户数据报协议

​ TCP/IP协议簇有两个主要协议,一个是传输层的TCP协议,一个是网络层的IP协议。

TCP:

​ 使用TCP协议前,要建立TCP连接(三次握手),创建出传输数据通道

​ TCP协议进行通信的两个应用进程:客户端、服务端

​ 传输完毕后,需要释放建立的传输数据通道(四次挥手)

三次握手:

TCP报文:

image-20211003155835494

32位序号就是seq

32位确认序号就是ack(对上一次发送来的报文表示确认的序号)

六个标志位

URG

ACK:确认标志位

PSH

RST

SYN:发起一个新的连接(1)

FIN:结束一个连接(1)

image-20211003154030771

此时的x、y、z是随机的。传输的时候就不是了!

为啥z不是x+1?

为什么要三次才可以建立连接:因为三次是服务端和客户端互相确认可以收到消息 最少的次数。

四次挥手:

一般是客户端请求断开连接,但是服务端也能请求断开连接。

image-20211003161039064

为啥要四次才能断开连接:因为请求方请求断开连接的时候,很有可能被断开方来不及释放socket资源,所以要进行确认。

import org.junit.Test;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class TCPTest {
    @Test
    public void clientTest(){
        Socket socket=null;
        OutputStream outputStream=null;
        try {
            InetAddress inetAddress=InetAddress.getByName("127.0.0.1");
            socket=new Socket(inetAddress,8899);
            outputStream=socket.getOutputStream();
            Scanner scanner=new Scanner(System.in);
            while(true){
                String str=scanner.nextLine();
                if("exit".equalsIgnoreCase(str)){
                    socket.shutdownOutput();
                    break;
                }
                outputStream.write(str.getBytes());
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if(outputStream!=null){
                    outputStream.close();
                }
                if(socket!=null){
                    socket.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    @Test
    public void serverTest(){
        ServerSocket serverSocket=null;
        InputStream inputStream=null;
        //InputStreamReader inputStreamReader=null;
        ByteArrayOutputStream byteArrayOutputStream=null;
        try {
            serverSocket=new ServerSocket(8899);
            while(true){
                Socket socket=serverSocket.accept();//阻塞式监听
                inputStream=socket.getInputStream();
              /* inputStreamReader=new InputStreamReader(inputStream,"utf-8");
                int len=-1;
                while((len=inputStreamReader.read())!=-1){
                    System.out.println((char)len);
                }*/
                byteArrayOutputStream=new ByteArrayOutputStream();
                byte[] bytes=new byte[10];
                int len=-1;
                while((len=inputStream.read(bytes))!=-1){
                    //System.out.println(new String(bytes,0,len));
                    byteArrayOutputStream.write(bytes,0,len);
                }
                System.out.println(byteArrayOutputStream.toString());
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                /*if(inputStreamReader!=null){
                    inputStreamReader.close();
                }*/
                if(byteArrayOutputStream!=null){
                    byteArrayOutputStream.close();
                }
                if(serverSocket!=null){
                    serverSocket.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }

    }

}

import org.junit.Test;

import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class TCPTest {
    @Test
    public void clientTest(){
        Socket socket=null;
        OutputStream outputStream=null;
        InputStream inputStream=null;
        InputStreamReader inputStreamReader=null;
        try {
            InetAddress inetAddress=InetAddress.getByName("127.0.0.1");
            socket=new Socket(inetAddress,8899);
            outputStream=socket.getOutputStream();
            byte[] buff=new byte[10];
            int len=-1;
            FileInputStream fileInputStream=new FileInputStream("C:\\Users\\26779\\Desktop\\老婆.jpg");
            while((len=fileInputStream.read(buff))!=-1){
                outputStream.write(buff,0,len);
            }
            fileInputStream.close();
            socket.shutdownOutput();
            inputStream=socket.getInputStream();
            inputStreamReader=new InputStreamReader(inputStream);
            int data=-1;
            while((data=inputStreamReader.read())!=-1){
                System.out.print((char)data);
            }
            System.out.println();

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

    @Test
    public void serverTest(){
        ServerSocket serverSocket=null;
        InputStream inputStream=null;
        OutputStream outputStream=null;
        try {
            serverSocket=new ServerSocket(8899);
            Socket socket=serverSocket.accept();//阻塞式监听
            inputStream=socket.getInputStream();
            byte[] bytes=new byte[10];
            int len=-1;
            FileOutputStream fileOutputStream=new FileOutputStream("C:\\Users\\26779\\Desktop\\老婆1.jpg");
            while((len=inputStream.read(bytes))!=-1) {
                fileOutputStream.write(bytes, 0, len);
            }
            fileOutputStream.close();
            outputStream=socket.getOutputStream();
            outputStream.write("结束".getBytes());

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

    }

}
UDP:

​ 将数据、源、目的都封装成为数据报,不需要建立连接

​ 每个数据报大小限制为64k

​ 发送时不管对方是否准备好的,接收方也没有确认收到的机制

​ 可以进行广播

​ 传输结束无需释放资源

UDP实现聊天:
Receiver:
package com.geng.talk;

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

public class Receiver implements Runnable{
    private int fromPort;
    DatagramPacket datagramPacket;
    DatagramSocket datagramSocket;

    public Receiver(int fromPort) {
        this.fromPort = fromPort;
        try{
            datagramSocket=new DatagramSocket(fromPort);
            byte[] data=new byte[1024];
            datagramPacket=new DatagramPacket(data,0,data.length);
        }
        catch (Exception e){
            e.printStackTrace();
        }
    }

    @Override

    public void run() {
        try{
            while(true){
                datagramSocket.receive(datagramPacket);
                String str=new String(datagramPacket.getData(),0,datagramPacket.getData().length);
                System.out.println("IP: "+datagramPacket.getAddress()+" 端口号: "+datagramPacket.getPort()
                        +": "+str);
                if("#end".equals(str)){
                    break;
                }
            }
            datagramSocket.close();
        }
        catch (Exception e){
            e.printStackTrace();
        }
    }
}



Sender:


package com.geng.talk;

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

public class Sender implements Runnable{
    private int toPort;
    private int selfPort;
    private String toIp;
    private DatagramSocket datagramSocket;
    private DatagramPacket datagramPacket;
    private  BufferedReader cin;
    public Sender(int toPort, int selfPort, String toIp) {
        this.toPort = toPort;
        this.selfPort = selfPort;
        this.toIp = toIp;
        cin=new BufferedReader(new InputStreamReader(System.in));
        try{
            datagramSocket=new DatagramSocket(this.selfPort);
        }
        catch (Exception e){
            e.printStackTrace();
        }
    }

    @Override
    public void run(){

        try{
            while(true){
                String str=cin.readLine();
                datagramPacket=new
                        DatagramPacket(str.getBytes()
                        ,0,str.getBytes().length,new InetSocketAddress(this.toIp,this.toPort));
                datagramSocket.send(datagramPacket);
                if("#end".equals(str)){
                    break;
                }
            }
            datagramSocket.close();
        }
        catch (Exception e){
            e.printStackTrace();
        }
    }
}

Teacher:

package com.geng.talk;

public class Teacher {
public static void main(String[] args){
new Thread(new Receiver(9090)).start();
new Thread(new Sender(9999,6666,"localhost")).start();
}
}

Student:

package com.geng.talk;

public class Student {
public static void main(String[] args){
new Thread(new Receiver(9999)).start();
new Thread(new Sender(9090,5555,"localhost")).start();
}
}

URL:统一资源定位符

表示Internet上面的某一个资源的地址

URL由五部分组成:

<传输协议>://<主机名(域名)(ip)>:<端口号>/<文件名>#片段名?参数列表

@Test
public void test01(){
    try {
        URL url=new URL("http://localhost:8080/springmvc/index.jsp?password=123&name=geng");
        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());//获取参数列表
    }catch (MalformedURLException e){
        e.printStackTrace();
    }

}
public static void main(String[] args) throws Exception {
    //创建一个url
    URL url=new URL("http://www.cnpaf.net/Class/HTTP/200811/23277.html");
    //打开这个url(打开这个资源)
    HttpURLConnection httpURLConnection=(HttpURLConnection)url.openConnection();
    
    InputStream inputStream=httpURLConnection.getInputStream();
    FileOutputStream fileOutputStream=new FileOutputStream("f.m4a");
    byte[] buffer=new byte[1024];
    int len;
    while((len=inputStream.read(buffer))!=-1){
        fileOutputStream.write(buffer,0,buffer.length);
    }
    fileOutputStream.close();
    inputStream.close();
    httpURLConnection.disconnect();
}
posted on 2021-10-08 19:22  gyp666  阅读(36)  评论(0)    收藏  举报