JavaSE-网络编程总结


1. InetAddress类

  1. InetAddress类表示Internet协议地址,其常用方法有:

    // 获取:主机名/主机IP;主机名称可以是机器名称,也可以是IP地址
    static InetAddress getByName(String host)
    // 获取:主机名
    String getHostName()
    // 获取:主机IP
    String getHostAddress()
    
  2. 127.0.0.1是回送地址,即localhost,指本地机,一般用来测试使用。

  3. InetAddress使用示例:

    import java.net.InetAddress;
    import java.net.UnknownHostException;
    
    public class InetAddressTest {
        public static void main(String[] args) throws UnknownHostException {
            InetAddress localhost = InetAddress.getByName("127.0.0.1");
            String hostName = localhost.getHostName();
            String hostAddress = localhost.getHostAddress();
            System.out.println(localhost);
            System.out.println(hostName);
            System.out.println(hostAddress);
            /**
             * 运行结果:
             * www.liu2m.com/127.0.0.1
             * www.liu2m.com
             * 127.0.0.1
             */
        }
    }
    

2. UDP通信

  1. Java为UDP客户端和服务端提供了DatagramSocket类

  2. UDP发送数据的步骤:

    1. 创建客户端的DatagramSocket对象:new DatagramSocket()
    2. 将待发送数据打包:new DatagramPacket(byte[] buf, int length, InetAddress address, int port)
    3. 调用DatagramSocket对象的方法发送数据:send(DatagramPacket p)
    4. 关闭客户端的DatagramSocket对象:close()
  3. UDP接收数据的步骤:

    1. 创建服务端的DatagramSocket对象:new DatagramSocket(int port)
    2. 创建一个数据包来存储接收到数据:new DatagramPacket(byte[] buf, int length)
    3. 调用DatagramSocket对象的方法接收数据:receive(DatagramPacket p)
    4. 调用DatagramPacket对象的方法解析收到的数据包:getData()、getLength()
    5. 关闭服务端的DatagramSocket对象:close()
  4. UDP发送端程序示例:

    import java.io.*;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    
    /**
     * UDP发送端:
     */
    public class UDPClient {
        public static void main(String[] args) throws IOException {
            // 1. 创建客户端的DatagramSocket对象
            String host = "127.0.0.1";
            int port = 22361;
            DatagramSocket ds = new DatagramSocket();
    
            // 2. 装饰标准输入流
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            String line;
            System.out.println("You can exit the program by typing exit");
    
            while ((line = br.readLine()) != null) {
                // 3. 将待发送数据打包
                DatagramPacket dp = new DatagramPacket(line.getBytes(), line.length(), InetAddress.getByName(host), port);
    
                // 4. 调用DatagramSocket对象的方法发送数据
                ds.send(dp);
    
                if ("exit".equals(line)) {
                    break;
                }
            }
            ds.disconnect();
            // 5. 释放资源
            br.close();
            ds.close();
        }
    }
    
  5. UDP接收端程序示例:

    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    
    /**
     * UDP接收端:
     */
    public class UDPServer {
        public static void main(String[] args) throws IOException {
            // 1. 创建服务端的DatagramSocket对象
            int port = 22361;
            DatagramSocket ds = new DatagramSocket(port);
    
            byte[] bytes = new byte[1024];
            while (true) {
                // 2. 创建一个数据包来存储接收到数据
                DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
    
                // 3. 调用DatagramSocket对象的方法接收数据
                ds.receive(dp);
    
                // 4. 调用DatagramPacket对象的方法解析收到的数据包
                String data = new String(dp.getData(), 0, dp.getLength());
                System.out.println(data);
    
                if ("exit".equals(data)) {
                    break;
                }
            }
            // 5. 释放资源
            ds.close();
        }
    }
    

3. TCP通信

  1. Java为TCP客户端提供了Socket类;为TCP服务端提供了ServerSocket类

  2. TCP发送数据的步骤:

    1. 创建客户端的Socket对象并将其连接到服务端:new Socket(String host, int port)
    2. 获取Socket对象的输出流来写数据:getOutputStream()
    3. 关闭发送端的Socket对象:close()
  3. TCP接收数据的步骤:

    1. 创建服务端的ServerSocket对象:new ServerSocket(int port)
    2. 调用ServerSocket对象的方法监听客户端连接并返回Socket:accept()
    3. 获取Socket对象的输入流来读数据:getInputStream()
    4. 关闭accept()返回的Socket对象:close()
    5. 关闭发送端的ServerSocket对象:close()
  4. 多线程上传文件示例:TCP发送端

    import java.io.*;
    import java.net.Socket;
    
    /**
     * 文件上传:TCP客户端
     * 1. 创建Socket对象并将其连接到服务端
     * 2. 使用FileInputStream读取待上传文件
     * 3. 获取Socket对象的输出流来给服务端写数据
     * 4. 禁用Socket对象的输出流;任何先前写入的数据将被发送,随后是TCP的正常连接终止序列
     * 由于read方法在检测到流的结尾或抛出异常之前会阻塞,因此客户端应给服务端一个结束标志
     * 5. 获取Socket对象的输入流来读服务端返回的数据
     * 6. 释放资源
     */
    public class TCPClient {
        public static void main(String[] args) throws IOException {
            // 1. 创建客户端的Socket对象并将其连接到服务端
            String host = "127.0.0.1";
            int port = 22361;
            Socket socket = new Socket(host, port);
            // 2. 使用FileInputStream读取待上传文件
            String filePath = "D:\\upload.txt";
            FileInputStream fis = new FileInputStream(filePath);
            // 3. 获取Socket对象的输出流来写数据
            OutputStream socketOut = socket.getOutputStream();
            byte[] bytes = new byte[1024];
            int len = 0;
            while ((len = fis.read(bytes)) != -1) {
                // 给服务端写数据
                socketOut.write(bytes, 0, len);
            }
            // 4. 禁用Socket对象的输出流;任何先前写入的数据将被发送,随后是TCP的正常连接终止序列
            socket.shutdownOutput();
            // 5. 获取Socket对象的输入流来读服务端返回的数据
            InputStream socketIn = socket.getInputStream();
            int receiveLen = socketIn.read(bytes);
            System.out.println(new String(bytes, 0, receiveLen));
            // 6. 释放资源
            fis.close();
            socket.close();
        }
    }
    
  5. 多线程上传文件示例:TCP接收端

    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    /**
     * 文件上传:TCP服务端
     * 1. 创建服务端的ServerSocket对象
     * 2. 调用ServerSocket对象的方法监听客户端连接并返回Socket
     * 线程完成:
     * 3. 获取Socket对象的输入流来读服务端上传的数据
     * 4. 使用FileOutputStream将读取到的文件写到磁盘
     * 5. 获取Socket对象的输出流来给服务端写回复
     * 6. 释放资源
     */
    public class TCPServer {
        public static void main(String[] args) throws IOException {
            // 1. 创建服务端的ServerSocket对象
            int port = 22361;
            ServerSocket serverSocket = new ServerSocket(port);
            // 获取线程池
            ExecutorService es = Executors.newFixedThreadPool(20);
            while (true) {
                // 2. 调用ServerSocket对象的方法监听客户端连接并返回Socket
                Socket socket = serverSocket.accept();
                // 为每一个客户端提交一个线程
                es.submit(new UploadThread(socket));
            }
            // es.shutdown();
            // serverSocket.close();
        }
    }
    
  6. 多线程上传文件示例:上传线程

    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    
    /**
     * 文件上传:上传线程
     */
    public class UploadThread implements Runnable {
        private Socket socket = null;
    
        public UploadThread(Socket socket) {
            this.socket = socket;
        }
    
        @Override
        public void run() {
            try {
                // 3. 获取Socket对象的输入流来读服务端上传的数据
                InputStream socketIn = socket.getInputStream();
                // 4. 使用FileOutputStream将读取到的文件写到磁盘
                String uploadPath = "D:\\upload\\upload_" + System.currentTimeMillis() + ".txt";
                FileOutputStream fos = new FileOutputStream(uploadPath);
                byte[] bytes = new byte[1024];
                int len = 0;
                while ((len = socketIn.read(bytes)) != -1) {
                    // 给磁盘写数据
                    fos.write(bytes, 0, len);
                }
                // 5. 获取Socket对象的输出流来给服务端写回复
                OutputStream socketOut = socket.getOutputStream();
                socketOut.write("Uploaded successfully".getBytes());
                // 6. 释放资源
                fos.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

4. 模拟B/S服务器

  1. 服务端:

    import java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    /**
     * 模拟B/S服务器:
     * 1. 创建服务端的ServerSocket对象
     * 2. 调用ServerSocket对象的方法监听客户端连接并返回Socket
     * 线程完成:
     * 3. 获取Socket对象的输入流
     * 装饰Socket对象的输入流
     * 读取请求的第一行
     * 在请求的第一行中分离出uri
     * 4. 获取Socket对象的输出流
     * 5. 使用FileInputStream来读取浏览器请求的文件
     * 向浏览器回复HTTP协议
     * 向浏览器回复数据
     * 6. 释放资源
     */
    public class WebServer {
        public static void main(String[] args) throws IOException {
            // 1. 创建服务端的ServerSocket对象
            int port = 22361;
            ServerSocket serverSocket = new ServerSocket(port);
    
            // 获取线程池
            ExecutorService es = Executors.newFixedThreadPool(20);
    
            while (true) {
                // 2. 调用ServerSocket对象的方法监听客户端连接并返回Socket
                Socket socket = serverSocket.accept();
                // 为每一个客户端提交一个线程
                es.submit(new ResponseThread(socket));
            }
            // es.shutdown();
            // serverSocket.close();
        }
    }
    
  2. 响应线程:

    import java.io.*;
    import java.net.Socket;
    
    /**
     * 响应线程
     */
    public class ResponseThread implements Runnable {
        private Socket socket;
    
        public ResponseThread(Socket socket) {
            this.socket = socket;
        }
    
        @Override
        public void run() {
            try {
                // 3. 获取Socket对象的输入流
                InputStream socketIn = socket.getInputStream();
                // 装饰Socket对象的输入流
                BufferedReader br = new BufferedReader(new InputStreamReader(socketIn));
                // 读取请求的第一行
                String s = br.readLine();
                // 在请求的第一行中分离出uri
                String uri = s.split(" +")[1].substring(1);
    
                // 4. 获取Socket对象的输出流
                OutputStream socketOut = socket.getOutputStream();
    
                System.out.println(uri);
                // 5. 使用FileInputStream来读取浏览器请求的文件
                FileInputStream fis = new FileInputStream(uri);
                // 向浏览器回复HTTP协议
                socketOut.write("HTTP/1.1 200 OK\r\n".getBytes());
                socketOut.write("Content-Type:text/html\r\n".getBytes());
                socketOut.write("\r\n".getBytes());
    
                byte[] bytes = new byte[1024];
                int len = 0;
                while ((len = fis.read(bytes)) != -1) {
                    // 向浏览器回复数据
                    socketOut.write(bytes, 0, len);
                }
    
                // 6. 释放资源
                br.close();
                fis.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

若有错误或补充,欢迎私信

JavaSE网络编程采用的是基于TCP/IP协议的网络模型。这个模型包括客户端和服务器端两部分。客户端通过套接字(Socket)与服务器建立连接,服务器则监听客户端的连接请求并进行响应。 在Java中,可以使用Socket类和ServerSocket类来实现网络编程Socket类用于建立客户端与服务器之间的通信连接,而ServerSocket类则用于创建服务器端的套接字,监听并接受客户端的连接请求。 客户端通过创建Socket对象,指定服务器的IP地址和端口号,然后通过Socket对象的方法与服务器进行通信。服务器端通过创建ServerSocket对象,指定服务器要监听的端口号,并通过accept()方法接受客户端的连接请求。一旦建立了连接,客户端和服务器端就可以通过输入流和输出流来进行数据的传输。 网络模型是基于TCP/IP协议的,因此可以使用Java的InputStream和OutputStream来进行数据的读写。客户端可以通过InputStream从服务器端接收数据,通过OutputStream向服务器端发送数据。服务器端则可以通过InputStream接收客户端发送的数据,通过OutputStream向客户端发送数据。 总结来说,JavaSE网络编程采用的是基于TCP/IP协议的网络模型,通过Socket和ServerSocket来实现客户端和服务器端之间的通信。通过InputStream和OutputStream来进行数据的读写。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [JavaSE——网络编程](https://blog.csdn.net/yzl1293346757/article/details/126192384)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [JavaSE学习——网络编程](https://blog.csdn.net/Demon_and_Angle_/article/details/126387829)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值