Java 网络编程case

Java 网络编程

网络编程三要素

  • IP 地址:设备在网络中的地址,是唯一的标识。
  • 端口号:应用程序在设备中的唯一标识。取值范围 0 ~ 65535,一般 0 ~1023 之间的端口用于固定网络服务或系统应用,一般自己使用 1024 以上的端口。一个端口只能被一个应用程序使用。
  • 协议:数据在网络中传输的规则,常见协议有 UDP 和 TCP。

InetAddress 类

该类表示 IP 地址。

  • getByName:根据主机名获取 InetAddress 对象。
  • getHostName:获取主机名。
  • getHostAddress:以字符串形式获取 IP 地址。

例:

public static void main(String[] args) throws UnknownHostException {
    InetAddress inetAddress = InetAddress.getByName("localhost");
    System.out.println("主机名为:" + inetAddress.getHostName());
    System.out.println("IP地址为:" + inetAddress.getHostAddress());
}

UDP 通信

UDP 的三种通信方式:

单播

发送端代码:

public class UDPClient {

    public static void main(String[] args) throws Exception {
        // 创建发送端 socket 对象
        DatagramSocket socket = new DatagramSocket();
        // 打包要发送的数据
        byte[] bytes = "HELLO UDP".getBytes();
        InetAddress address = InetAddress.getByName("localhost");
        int port = 8080;
        DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, port);
        // 发送数据
        socket.send(packet);
        // 释放资源
        socket.close();
    }

}

接收端代码:

public class UDPServer {

    public static void main(String[] args) throws Exception{
        // 创建接收端 socket 对象,表示从 8080 端口接收数据
        DatagramSocket socket = new DatagramSocket(8080);
        // 准备接收数据
        byte[] bytes = new byte[1024];
        DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
        // 接收数据
        socket.receive(packet);
        // 获取数据
        int length = packet.getLength();
        System.out.println(new String(bytes, 0, length));
        // 释放资源
        socket.close();
    }

}

如果接收端没有接收到数据,会在 socket.receive(packet); 处阻塞。


组播

组播地址 224.0.0.0 ~ 239.255.255.255,其中 224.0.0.0 ~224.0.0.255 不可用。

发送端代码:

public class UDPClient {

    public static void main(String[] args) throws Exception {
        // 创建发送端 socket 对象
        DatagramSocket socket = new DatagramSocket();
        // 打包要发送的数据
        byte[] bytes = "HELLO UDP".getBytes();
        // 224.0.1.0 表示组播地址
        InetAddress address = InetAddress.getByName("224.0.1.0");
        int port = 8080;
        DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, port);
        // 发送数据
        socket.send(packet);
        // 释放资源
        socket.close();
    }

}

接收端代码:

public class UDPServer {

    public static void main(String[] args) throws Exception{
        // 创建接收端 socket 对象(注意使用 MulticastSocket),从 8080 端口接收数据,
        MulticastSocket socket = new MulticastSocket(8080);
        // 准备接收数据
        byte[] bytes = new byte[1024];
        DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
        // 把当前计算机绑定到组播地址
        socket.joinGroup(InetAddress.getByName("224.0.1.0"));
        // 接收数据
        socket.receive(packet);
        // 获取数据
        int length = packet.getLength();
        System.out.println(new String(bytes, 0, length));
        // 释放资源
        socket.close();
    }

}

广播

发送端代码:

public class UDPClient {

    public static void main(String[] args) throws Exception {
        // 创建发送端 socket 对象
        DatagramSocket socket = new DatagramSocket();
        // 打包要发送的数据
        byte[] bytes = "HELLO UDP".getBytes();
        InetAddress address = InetAddress.getByName("255.255.255.255");
        int port = 8080;
        DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, port);
        // 发送数据
        socket.send(packet);
        // 释放资源
        socket.close();
    }

}

接收端代码:

public class UDPServer {

    public static void main(String[] args) throws Exception{
        // 创建接收端 socket 对象,表示从 8080 端口接收数据
        DatagramSocket socket = new DatagramSocket(8080);
        // 准备接收数据
        byte[] bytes = new byte[1024];
        DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
        // 接收数据
        socket.receive(packet);
        // 获取数据
        int length = packet.getLength();
        System.out.println(new String(bytes, 0, length));
        // 释放资源
        socket.close();
    }

}

TCP 通信

TCP 在通信两端各建立一个 Socket 对象,发送端是 Socket,接收端是 ServerSocket,通信之前要保证连接已经建立。

发送端代码:

public class TCPClient {

    public static void main(String[] args) throws Exception{
        // 创建发送端 socket
        Socket socket = new Socket("localhost", 8080);
        // 获取字节输出流
        OutputStream os = socket.getOutputStream();
        // 写数据
        os.write("hello tcp".getBytes());
        // 释放资源
        os.close();
        socket.close();
    }

}

接收端代码:

public class TCPServer {

    public static void main(String[] args) throws Exception{
        // 创建接收端 socket
        ServerSocket serverSocket = new ServerSocket(8080);
        // 获取客户端连接 socket,获取不到将阻塞
        Socket socket = serverSocket.accept();
        // 获取字节输入流
        InputStream is = socket.getInputStream();
        // 读数据,如果发送端没有释放资源会阻塞
        int b;
        while ((b = is.read()) != -1){
            System.out.print((char)b);
        }
        // 释放资源
        is.close();
        socket.close();
        serverSocket.close();
    }

}

TCP 练习1:双方互相发送数据

客户端:发送数据,接收服务器反馈。

public class TCPClient {

    public static void main(String[] args) throws Exception{
        // 创建发送端 socket
        Socket socket = new Socket("localhost", 8080);
        // 获取字节输出流并发送数据
        OutputStream os = socket.getOutputStream();
        os.write("hello tcp".getBytes());
        // 写一个结束标记,关闭输出流
        socket.shutdownOutput();
        // 获取字符输入流并读取反馈
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String line;
        while ((line = br.readLine()) != null){
            System.out.print(line);
        }
        // 释放资源
        br.close();
        os.close();
        socket.close();
    }

}

服务器:接收数据,给出反馈。

public class TCPServer {

    public static void main(String[] args) throws Exception{
        // 创建接收端 socket
        ServerSocket serverSocket = new ServerSocket(8080);
        // 获取客户端连接 socket,获取不到将阻塞
        Socket socket = serverSocket.accept();
        // 获取字节输入流并读取数据
        InputStream is = socket.getInputStream();
        int b;
        while ((b = is.read()) != -1){
            System.out.print((char)b);
        }
        // 获取字符输出流并反馈
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        bw.write("已收到");
        // 释放资源
        bw.close();
        is.close();
        socket.close();
        serverSocket.close();
    }

}

TCP 练习2:文件上传

客户端:将本地文件上传到服务器,接收服务器反馈。

public class FileUpload {

    public static void main(String[] args) throws Exception{
        // 创建客户端 socket
        Socket socket = new Socket("localhost", 8080);
        // 要上传的文件
        File file = new File("C:\\a.jpg");
        // 本地字节输入流,读取文件
        InputStream is = new FileInputStream(file);
        // 网络字节输出流,上传文件
        OutputStream os = socket.getOutputStream();
        byte[] bytes = new byte[1024];
        int read;
        while ((read = is.read(bytes)) != -1){
            os.write(bytes, 0, read);
        }
        socket.shutdownOutput();
        // 接收服务端提示
        is = socket.getInputStream();
        while ((read = is.read()) != -1){
            System.out.print((char)read);
        }
        // 释放资源
        is.close();
        os.close();
        socket.close();
    }
}

服务器:接收客户端上传的文件,接收成功后给出反馈。

public class FileReceive {

    public static void main(String[] args) throws Exception{
        // 创建服务端 socket
        ServerSocket serverSocket = new ServerSocket(8080);
        // 接收客户端 socket
        Socket socket = serverSocket.accept();
        // 网络字节输入流,读取文件
        InputStream is = socket.getInputStream();
        // 本地字节输出流,保存到对应文件夹
        OutputStream os = new FileOutputStream(new File("C:\\b.jpg"));
        byte[] bytes = new byte[1024];
        int read;
        while ((read = is.read(bytes)) != -1){
            os.write(bytes, 0, read);
        }
        // 提示客户端上传成功
        os = socket.getOutputStream();
        os.write("file upload successfully".getBytes());
        // 释放资源
        os.close();
        is.close();
        socket.close();
        serverSocket.close();
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章