【Java】Socket Programming 网络编程

Java提供了网路相关的类库,无痛连网,底层细节交给JVM控制

Java实现了一个跨平台的网络库,我们开发面对的是一个统一的网路编程环境

 

目的:

直接或者间接的通过网络协议和其他计算机数据交互,通讯

主要问题:

准确定位网络上的一台计算机或者多台,定位主机上的特定的应用

找到主机后如何可靠高效的进行数据传输

 

通信要素:

IP 和 端口号

TCP/IP协议

 

IP:是计算机再网络中的唯一标识

本地回环地址;127.0.0.1 主机名:LocalHost

IP地址分类:IPV4 IPV6

v4 - 4字节组成,4个0 - 255 大概42亿总可用,北美30亿,亚洲4亿,2011耗尽,

v6 - 128位 16字节 8个无符号整数,每个整数用4个十六进制位表示,每个数用冒号分隔

按地址分类方式:公网地址【万维网使用】 和私有地址【局域网使用】

192.168.0.0 - 192.168.255.255 为组织机构内部使用

    static void socket01IP_Address() throws UnknownHostException {
        // DNS Domain Name System
        // localhost/127.0.0.1 本机地址
        InetAddress localhost = InetAddress.getByName("localhost");
        System.out.println(localhost);

        InetAddress a = InetAddress.getByName("www.cnblogs.com");
        System.out.println(a);
        // www.baidu.com/14.215.177.38
        // www.acfun.cn/117.21.225.193
        // www.bilibili.com/119.3.70.188
        // www.cnblogs.com/101.37.113.127

        InetAddress localHost = InetAddress.getLocalHost();
        System.out.println(localHost);

        String address = localHost.getHostAddress();
        String hostName = localHost.getHostName();

    }

 

端口号,是计算机上正在运行的进程(程序)

不同的进程不同的端口号

规定为一个16位的整数 0 - 65535

公认端口0 - 1023 预定义的服务通信占用 HTTP 80、FTP 21、Telnet 23

注册端口 1024 - 49151 分配给用户进程或者是应用程序 Tomcat8080、MySQL3306、Oracle1521、

动态端口/ 私有端口 49152 - 65535

套接字 = 端口号 + IP地址

 

TCP

- 建立连接,形成传输通道,

- 三次握手确认,点对点通信,可靠的

- TCP协议的两个应用进程 客户端、服务器

- 可进行大型数据的传输

- 传输完毕,释放已建立的连接、效率低

UDP

- 数据打包,无连接

- 每个包限制大小64KB

- 无论对方是否准备,接受方是否收到,都没有确认反馈

- 可广播发送

- 发送结束时,无序释放资源,开销小速度快

 

TCP

public class TCP_Test {
    @Test // 服务端
    public void server() throws Exception {
        // 创建服务器程序
        ServerSocket server = new ServerSocket(65000);

        Socket client = server.accept(); // 表示接受进来的客户端套接字

        InputStream inputStream = client.getInputStream();

        byte[] bytesBuffer = new byte[512];

        int len;

        while ((len = inputStream.read(bytesBuffer)) != -1){
            String str = new String(bytesBuffer,0,len);
            System.out.println(str);
        }

        System.out.println("来自服务器的消息:已收到客户端:" + client.getInetAddress().getHostAddress() + " 的消息");

        // 关闭资源
        inputStream.close();
        client.close();
        server.close();
    }

    @Test // 客户端
    public void client() throws Exception {

        // 这是要连接对方的socket信息,IP + port
        Socket client = new Socket(InetAddress.getByName("localhost"),65000);

        OutputStream outputStream = client.getOutputStream();
        outputStream.write("来自客户端发送的消息: Connect Success!!!".getBytes());

        // 流对象释放
        outputStream.close();

        // 套接字释放
        client.close();
    }
}

 

UDP

public class UDP_Test {

    @Test
    public void send() throws Exception {

        DatagramSocket ds = new DatagramSocket();

        java.lang.String message = "来自发送器的消息:Hello UDP!!!";
        byte[] bytes = message.getBytes();
        InetAddress localHost = InetAddress.getLocalHost();
        DatagramPacket dp = new DatagramPacket(bytes,0,bytes.length,localHost,65000);

        // 发送包
        ds.send(dp);

        ds.close();
    }

    @Test
    public void receive() throws Exception{
        DatagramSocket ds = new DatagramSocket(65000);

        byte[] buffer = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length);
        ds.receive(packet);

        System.out.println(new String(packet.getData(),0,packet.getLength()));

        ds.close();
    }

}

 

URL

Uniform Resource Locator 统一资源定位符,表示网络的某一资源地址

- 是一种具体的URI,URL可用来标识一个资源,指明如何locate这个资源

- 传输协议 主机名 端口号 文件名 片段名 ?参数列表

一般的端口号就是80

#片段名是锚点,定位到一个具体的部分

参数列表是一个KV对 ?k1=v1这样,如果是多个参数则使用&连接

public class URL_Test {
    public static void main(String[] args) throws Exception {
        String url = "https://www.ygo-sem.cn/photo/story-430.aspx";

        URL url_link = new URL(url);

        System.out.println("协议名:" + url_link.getProtocol());
        System.out.println("主机名:" + url_link.getHost());
        System.out.println("端口号:" + url_link.getPort()); // -1 表示未获取到
        System.out.println("文件路径:" + url_link.getPath());
        System.out.println("文件名:" + url_link.getFile());
        System.out.println("查询名:" + url_link.getQuery());
    }
}

 

posted @ 2020-04-22 21:42  emdzz  阅读(238)  评论(0编辑  收藏  举报