【JAVA】基础:网络(TCP/IP/UDP/HTTP)URL、Socket

IP地址: IP地址是我们电脑在网络中的唯一标记, 所有的电脑之间进行信息交互都是利用这个IP地址来进行识别。

端口号: ip地址唯一标示了通信实体,但是一个通信实体可以有多个通信程序同时提供网络服务。这个时候就要通过端口来区分开具体的通信程序。一个通信实体上不能有两个通信程序使用同一个端口号。

TCP/IP协议: IP协议规定了我们网络当中的每一台PC的唯一标记,TCP协议就规定数据传输的编码和解码的格式。网卡就是根据TCP/IP协议生产的不见,为电脑生产IP地址,组装TCP协议,都是由网卡完成。

UDP: 用户数据报协议,UDP是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传送目的地,至于能够达到目的地,达到目的地的时间以及内容的正确性都是不能保证的。

Telnet: Internet远程登录服务的标准协议和主要方式。

FTP: 文本传输协议。

HTTP: 超文本传送协议。是互联网上应用最为广泛的一种网络协议,是一个基于TCP和UDP的高级协议,主要用于网络之间数据传输,我们的web项目全是使用该协议。

HTTPS: 是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。

URL:

1、URL对象代表统一资源定位器,是指向互联网“资源”的指针。它是用协议名、主机、端口和资源组成,即满足如下格式:

 protocol://host:port/resourceName

 http://www.xxxxx.com/index.jsp

2、通过URL对象的一些方法可以访问该URL对应的资源:

 String getFile():获取该URL的资源名

 String getHost():获取主机名

 String getPath():获取路径部分

 int   getPort():获取端口号

3、通过URL获取数据并利用线程下载

import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;


public class Test {

    public static void main(String[] args) {

        //获取网络资源   https://www.baidu.com/img/bd_logo1.png
//      System.out.println(connection.getContentLength()); 

//      10 * 1024 / 10   == 10个线程,每一个读一段

            try {
                URL url = new URL("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1529561868526&di=fc4ed55264363524350598bb67f6c989&imgtype=0&src=http%3A%2F%2Fimg.zcool.cn%2Fcommunity%2F0114375543f8ec0000019ae948310f.jpg");
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();

                //未来我们就利用connection 去获取数据
                System.out.println(connection.getContentLength());
                byte b[] = new byte[8000];
                InputStream is = connection.getInputStream();
                long time = new Date().getTime();
                //注意,服务器给数据是按照他的规则给 每次很少, 所以我们循环获取数据
                while(true){
                    int num = is.read(b); //num = 读取数据的长度
                    //当读取到的数据为-1的时候,就表示没有数据
                    if(num==-1) {
                        break;
                    }else{
                        System.out.println("本次下载长苏:" + num + "字节");
                        FileOutputStream fos = new FileOutputStream("e:/a.png",true);
                        //由于每次读取的数据有效,我们不要吧整个byte数组写到硬盘, 而是要写入里面获取到的数据。
                        fos.write(b, 0, num);
                        fos.close();
                    }
                }
                long time1 = new Date().getTime();
                System.out.println(time1- time);    

            } catch (Exception e) {
                e.printStackTrace();
            }
    }
}

如果说需要使用多线程下载,会出现一个问题,线程的先后顺序不一致,导致存储数据时可能错位,所以我们需要使用一个能制定数据存在到那个位置的流,这个流就是RandomAccessFile

package com.test.down;

import java.io.FileOutputStream; 
import java.io.InputStream; 
import java.io.RandomAccessFile; 
import java.net.HttpURLConnection; 
import java.net.URL; 
import java.util.Date;

public class DownLoad implements Runnable{
public int start;
public int end;
public String urlStr;
public int point;

public DownLoad(int start, int end, String urlStr) {
    this.start = start;
    this.end = end;
    this.urlStr = urlStr;
    this.point = start;
}

public void run() {

    try {
        URL url = new URL(urlStr);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        //未来我们就利用connection 去获取数据
        //设置读取的长度??
        connection.setAllowUserInteraction(true);                   //设置读取点
        connection.setRequestProperty("Range", "bytes=" + start + "-" + end);
        connection.connect();
        byte b[] = new byte[8000];
        InputStream is = connection.getInputStream();
        long time = new Date().getTime();
        //注意,服务器给数据是按照他的规则给 每次很少, 所以我们循环获取数据
        while(true){
            int num = is.read(b); //num = 读取数据的长度
            //当读取到的数据为-1的时候,就表示没有数据
            if(num==-1) {
                break;
            }else{
                System.out.println("本次下载长度:" + num + "字节");
                RandomAccessFile random = new RandomAccessFile("d:/b.jpg","rw");
                //设置存放点
                random.seek(point);
                random.write(b, 0, num);
                point += num;
                random.close();
            }
        }
        long time1 = new Date().getTime();
        // System.out.println(time1- time);
  } catch (Exception e) {
        e.printStackTrace();
    }

}
}

Socket:

Socket又称套接字,是连接运行在网络上两个程序间的双向通讯的端点。

服务端:服务器程序将一个套接字绑定到一个特定的端口,并通过此套接字等待和监听客户端的连接请求。
客户端:客户端程序根据你服务器所在的主机名和端口号发出连接请求。
服务端和客户端两者之间的通信是通过Socket完成的。
1.创建简单的服务端、客户端
服务器端:

 public static void main(String[] args) throws IOException
        {
            //创建一个ServerSocket,用于监听客户端Socket连接请求
            ServerSocket ss = new ServerSocket(8888);
            System.out.println("server start");
            //采用循环方式监听客户端的请求
            while(true)
            {
                //侦听并接受到此套接字的连接。此方法在连接传入之前一直阻塞。
                Socket socket = ss.accept();
                OutputStream os = socket.getOutputStream();
                PrintStream ps = new PrintStream(os);
                ps.print("服务端的信息");
                ps.close();
                os.close();
                socket.close();
            }
        }

客户端:

public static void main(String[] args) throws IOException, Exception
    {
        Socket socket = new Socket("localhost",8888);
        InputStream is = socket.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String str = br.readLine();
        System.out.println(str);
        br.close();
        is.close();
        socket.close();
    }

2.整合多线程实现 及时聊天通信
一个读数据线程,一个写数据线程

写数据

    package com.test.client;
    
    import java.io.IOException; 
    import java.io.OutputStream; 
    import java.net.Socket; 
    import java.util.Scanner;
    
    public class WriteThread implements Runnable{
    Socket socket;
    
    public WriteThread( Socket s) {
        this.socket = s;
    }
    
    public void run() {
        try {
            OutputStream os = socket.getOutputStream();
            Scanner sc = new Scanner(System.in);
            while(true) {
                String word = sc.nextLine();
                byte b[] = word.getBytes();
                os.write(b);
                os.flush();
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    
    
    }
    } 

读数据

package com.test.client;

import java.io.IOException; 
import java.io.InputStream; 
import java.net.Socket;

public class ReadThread implements Runnable{
private Socket socket;
public String name;

public ReadThread( Socket s, String name){
    this.socket = s;
    this.name = name;
}

public void run() {
    try {
        InputStream in = socket.getInputStream();
        byte b[] = new byte[1024];

        while(true) {
            in.read(b);
            String word = new String(b);
            System.out.println(name + "说:" + word);
        }


    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}
}

客户端

package com.test.client;

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

public class Client {
public Client() {
    init();
}


public void init() {
    try {
        Socket s = new Socket("127.0.0.1", 9999);

        //启动读线程
        new Thread(new ReadThread(s,"服务器")).start();

        //启动写线程
        new Thread(new WriteThread(s)).start();


    } catch (UnknownHostException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


}


public static void main(String[] args) {
    new Client();
}
}

服务端

package com.test.client;

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

public class Server {
public Server() {
    try {
        ServerSocket server = new ServerSocket(9999);

        Socket s = server.accept();

        //启动读线程
        new Thread(new ReadThread(s, "客户端")).start();

        //启动写线程
        new Thread(new WriteThread(s)).start();

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

public static void main(String[] args) {
    new Server();
}
}

3.DataGramSocket:注意和TCP IP的区别 DataGramSocket 既是服务器又是客户端。
客户端

    package com.test.udp;
    
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.SocketException;
    
    //客户端
    public class TestClient {
    
        public static void main(String[] args) {
            try {
                DatagramSocket server = new DatagramSocket(8888);
    
                byte b[] = new byte[1024];
                DatagramPacket packet = new DatagramPacket(b, b.length);
    
                server.receive(packet);
    
                System.out.println("over" + new String(b));
    
    
                //将数据存储到硬盘上
    
    
    
            } catch (SocketException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
        }
    
    }

服务器

    package com.test.udp;
    
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.SocketException;
    
    //服务器
    public class TestServer {
    
        public static void main(String[] args) {
            try {
                DatagramSocket server = new DatagramSocket();
    
                byte buff[] = new byte[1024];
                buff = "zhangsan".getBytes();
    
                InetAddress ip = InetAddress.getByName("127.0.0.1");
                DatagramPacket packet = new DatagramPacket(buff, buff.length,ip,8888);
                server.send(packet);
                server.close();
    
            } catch (SocketException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
        }
    
    }

猜你喜欢

转载自blog.csdn.net/qq_42755008/article/details/85332411