网络编程

IP

inetAddress类,此类表示Internet协议(IP)地址

IP是用来定位节点/电脑的

InetAddress类常用方法

返回值类型方法名解释
InetAddressgetLocalHost()静态方法,返回本机的InetAddress对象
StringgetHostAddress()返回IP地址
StringgetHostName()返回计算机名
InetAddressgetByName()给定主机名,返回主机的InetAddress对象,主机名可以是www地址,或者是ip地址

示例代码

public class demo01 {
    public static void main(String[] args) throws UnknownHostException {
        
        //获取本地主机InetAddress对象
        InetAddress inetAddress = InetAddress.getLocalHost();

        //打印主机地址和主机名
        System.out.println("本机IP:"+inetAddress.getHostAddress());
        System.out.println("本机名:"+inetAddress.getHostName());

        //通过主机名获取主机InetAddress对象
        inetAddress = InetAddress.getByName("www.qkmango.top");
        
        System.out.println("主机IP:"+inetAddress.getHostAddress());
        System.out.println("主机名:"+inetAddress.getHostName());
    }
}

端口

端口是区分软件的 ,区分计算机中不同的进程

了解端口

在这里插入图片描述

InetSocketAddress类常用方法

返回值类型方法名解释
InetSocketAddressInetSocketAddress(“网址/IP地址”,端口)构造方法
inetAddressgetAddress()返回inetAddress类对象
StringgetHostName()返回主机名
intgetPort()返回主机端口号

URL

了解URL

URL是互联网三大基石之一:html、http、url

  • URI = Universal Resource Identifier 统一资源标志符,用来标识抽象或物理资源的一个紧凑字符串。
  • URL = Universal Resource Locator 统一资源定位符,一种定位资源的主要访问机制的字符串,一个标准的URL必须包括:protocol、host、port、path、parameter、anchor。
  • URN = Universal Resource Name 统一资源名称,通过特定命名空间中的唯一名称或ID来标识资源。

在这里插入图片描述

在www上,每个资源都有一个统一且唯一的地址,即统一资源定位符URL,

如:http://www.baidu.com:80/index.html?name=mango&age=19#a

​ 协议 主机名 端口 资源路径 参数列表

  • 协议 http
  • 主机名 www.baidu.com
  • 端口号 80
  • 资源路径 index.html
  • 参数列表

常用方法

返回值类型方法名解释
StringgetProtocol()获取协议
StringgetHost()获取主机名(域名、IP)
intgetPort()获取端口号
StringgetFile()请求资源,获取资源文件名,有路径,包括参数
StringgetPath()请求资源,获取资源文件路径,无参数
StringgetQuery()获取参数,获取此URL的查询名
StringgetRef()获取锚点

示例

public class demo01 {
    public static void main(String[] args) throws MalformedURLException {
        //创建一个URL
        URL url = new URL("http://www.baidu.com:80/index.html?name=mango&age=19#a");

        System.out.println("协议"+url.getProtocol());
        System.out.println("域名/IP"+url.getHost());
        System.out.println("端口号"+url.getPort());
        System.out.println("请求资源"+url.getFile()); //获取资源文件名,包括参数
        System.out.println("请求资源"+url.getPath()); //获取资源文件名
        System.out.println("参数"+url.getQuery());    //获取此URL的查询部分
        System.out.println("锚点"+url.getRef());      //获取锚点
    }
}

TCP编程

TCP的优点

可靠,稳定 TCP的可靠体现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源。 TCP的缺点: 慢,效率低,占用系统资源高,易被攻击 TCP在传递数据之前,要先建连接,这会消耗时间,而且在数据传递时,确认机制、重传机制、拥塞控制机制等都会消耗大量的时间,而且要在每台设备上维护所有的传输连接,事实上,每个连接都会占用系统的CPU、内存等硬件资源。

Socket类

socket即套接字,由IP/www和端口号构成的

常用构造方法
  • Socket(String host, int port) 传入主机地址和端口号
常用重要方法
返回值类型方法说明
InputStreamgetInputStream()返回此套接字的输入流
OutputStreamgetOutputStream()返回此套接字的输出流
voidclose()关闭此套接字
voidshutdownOutput()禁用此套接字的输出流
voidshutdownInput()禁用此套接字的输入流

当然还有其他的基本方法,如获取端口号等等,不一一列举

ServerSocket类

服务器端套接字,这个类实现了服务器套接字。 服务器套接字等待通过网络进入的请求

常用构造方法
  • ServerSocket(int port) 指定端口创建服务端套接字对象
常用方法
返回值类型方法说明
Socketaccept()获取客户端套接字,侦听要连接到此套接字并接受它
voidclose()关闭此套接字

客户端向服务端发送一个请求,服务端通过accept()接收取出请求,获得一个socket对象,服务端可客户端通过操作socket的输入输出流进行通信,客户端向服务端通过socket发送数据,发送完毕后,服务端要返回客户端数据的话,客户端要主动关闭socket的输出流,不然服务端会一直监听接收来自客户端的数据

  • TCP网络编程:客户端发送信息给服务端,并打印出来
public class demo01 {
    public static void main(String[] args) {
       new Thread(new SocketThread()).start();
       new Thread(new ServerSocketThread()).start();
    }
}

class SocketThread implements Runnable {
    @Override
    public void run() {
        //创建客户端套接字对象,指定服务端的IP和端口
        try(Socket socket = new Socket("127.0.0.1",3307);
            //通过客户端套接字获取输出流
            OutputStream os = socket.getOutputStream();
            BufferedReader isr = new BufferedReader(new InputStreamReader(System.in))) {
            while (true) {
                String msg = isr.readLine();
                //通过输出流写出信息
                os.write(msg.getBytes());
                if(msg.equals("exit")) {
                    break;
                }
            }
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class ServerSocketThread implements Runnable {
    @Override
    public void run() {
        //服务端指定端口,创建服务端套接字对象
        try(ServerSocket serverSocket = new ServerSocket(3307);
            //通过accept()方法获取客户端的套接字对象
            Socket socket = serverSocket.accept();
            //通过获取的套接字获取输入流
            InputStream is = socket.getInputStream();) {
            int len = -1;
            //写出信息,通过套接字将信息输出到客户端
            byte[] flush = new byte[1024];
            while ((len = is.read(flush)) != -1) {
                System.out.println("__________________");
                System.out.println("| "+new String(flush,0,len));
                System.out.println("| from:"+socket.getInetAddress());
                System.out.println("¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • TCP网络编程:客户端发送文件给服务端,并保存在本地,服务器并返回一个数据告诉客户端上传成功了
public class demo02 {
    public static void main(String[] args) {
        new Thread(new SocketThread()).start();
        new Thread(new ServerSocketThread()).start();
    }
}

//客户端
class SocketThread implements Runnable {
    @Override
    public void run() {
        //创建套接字对象
        try(Socket socket = new Socket("127.0.0.1",3307);
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream("Net/src/testfile/test.txt"));
            //获取套接字的输出流
            BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
            //获取套接字的输入流
            InputStream is = socket.getInputStream();) {
            //数据写出
            byte[] bytes = new byte[1024];
            int len = -1;
            while ((len = bis.read(bytes)) != -1) {
                bos.write(bytes,0,len);
            }
            System.out.println("传输完成");
            bos.flush();
            //数据写出完毕后关闭输出流,否则服务端会一直进行接收数据
            socket.shutdownOutput();
            //读取服务器发回的信息
            len = is.read(bytes);
            System.out.println(new String(bytes,0,len));
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

/**
 * 服务端
 */
class ServerSocketThread implements Runnable {
    @Override
    public void run() {
        try(ServerSocket serverSocket = new ServerSocket(3307);
        Socket socket = serverSocket.accept();
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("Net/src/testfile/test2.txt"));
        BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
            OutputStream os = socket.getOutputStream();) {
            byte[] bytes = new byte[1024];
            int len = -1;
            while ((len = bis.read(bytes)) != -1) {
                bos.write(bytes,0,len);
            }
            bos.flush();
            //传输完成后,客户端主动关闭客户端的输出流,那么服务端的输入流就会结束,
            // 否则服务端一直会接收数据不停
            //返回给客户端信息
            os.write("已经收到了,谢谢".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

UDP编程

UDP优点

快,比TCP稍安全 UDP没有TCP的握手、确认、窗口、重传、拥塞控制等机制,系统不保证UDP数据包一定能到达,也不保证什么时候能到达,UDP是一个无状态的传输协议,所以它在传递数据时非常快。

Java使用DatagramSocket代表UDP协议的Socket,DatagramSocket本身只是码头,不维护状态,不能产生IO流,它的唯一作用就是接收和发送数据报,Java使用DatagramPacket来代表数据报,DatagramSocket接收和发送的数据都是通过DatagramPacket对象完成的。

发送端使用步骤

  1. 创建服务端+端口
  2. 准备数据
  3. 打包(发送的地点及端口)
  4. 发送资源
  5. 关闭资源

接收端使用步骤

  1. 创建服务端+端口

  2. 准备接收容器

  3. 封装成包 new DatagramPacket(byte[] b,int length)

  4. 接收数据,使用 DatagramSocket的实例的 receive(DatagramPacket)方法进行接收

    阻塞式接收,直到接收到一个数据为止

  5. 分析数据

  6. 关闭资源

示例

  • 发送端发生一句话,接收端接收并显示
public class demo01 {
    public static void main(String[] args) {
        new Thread(new Send()).start();
        new Thread(new Receive()).start();
    }
}

//发送端
class Send implements Runnable {
    @Override
    public void run() {
        //1. 创建客户端,DatagramSocket只负责收发数据
        DatagramSocket socket = null;
        //2. 创建数据报,DatagramPacket来代表数据报
        DatagramPacket packet = null;
        //创建数据
        byte[] data = "嘿嘿嘿,你好呀".getBytes();
        try {
            InetAddress inet = InetAddress.getLocalHost();
            socket = new DatagramSocket();
            //3. 打包数据,指明主机地址和端口号
            packet = new DatagramPacket(data,0,data.length,inet,3307);
            //4. 发送数据
            socket.send(packet);
            //5. 关闭数据
            socket.close();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(socket != null) {
                socket.close();
            }
        }
    }
}

//接收端
class Receive implements Runnable {
    @Override
    public void run() {
        //1. 创建服务端,DatagramSocket只负责收发数据
        DatagramSocket socket = null;
        //2. 创建数据报,DatagramPacket来代表数据报
        DatagramPacket packet = null;
        try {
            //3. 数据接收容器
            byte[] data = new byte[100];
            //4. 指明服务端端口
            socket = new DatagramSocket(3307);
            //5. 数据封装程包
            packet = new DatagramPacket(data,0,data.length);
            //6. 接收数据
            socket.receive(packet);
            //输出数据,通过getData()方法获取数据报存储的数据,getLength()获取数据的实际接收的长度
            System.out.println(new String(packet.getData(),0,packet.getLength()));
            //7. 关闭数据
            socket.close();
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(socket != null) {
                socket.close();
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值