zoukankan      html  css  js  c++  java
  • Java 网络编程

    软件结构 & 网络通信协议

    C/S结构: Client/Server 结构, 是指客户端和服务器结构, 常见的程序有 QQ, 迅雷等软件

    B/S结构: Browser/Server结构, 是指浏览器和服务器结构, 常见的程序有 Google, Firefox 等

    两种结构各有优势, 都离不开网络的支持, 网络编程, 就是在一定协议下, 实现两台计算机的通信的程序.

    TCP协议

    面向连接的通信, 客户端和服务端必须经过3次握手, 建立逻辑连接, 才能通信

    通信的步骤:

    1. 服务端启动

    2. 客户端请求服务端, 建立逻辑连接 (IO对象 socket)

    3. 客户端和服务端之间通过 socket 进行通信

    多个客户端同时和服务端交互, 在服务端有一个 accept() 方法, 获取到请求的客户端对象

    服务端是没有 IO 对象的, 它可以获取到客户端的 socket, 来和每个客户端通信

    ServerSocket & Socket 类

    Serversocket

    java.net.ServerSocket: 实现了服务端套接字, 等待客户端套接字请求

    构造方法:

    public ServerSocket(int port): 创建绑定到指定端口号的服务器套接字

    成员方法:

    1. public Socket accept(): 侦听并返回客户端的套接字, 然后使用客户端的套接字与客户端进行交互

    2. public void close(): 关闭套接字, 释放资源

    Socket

    java.net.Socket: 实现了客户端的套接字, 套接字是两台机器之间通信的端点

    套接字是包含了 IP 地址和端口号的网络单位

    构造方法:

    Socket(String host, int port): 创建一个流套接字, 并将其连接到指定主机, 指定端口

    成员方法:

    1. OutputStream getOutputStream(): 返回套接字的输出流

    2. InputStream getInputStream(): 返回套接字的输入流

    3. void close(): 关闭此套接字

    demo:

    server

    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class TCPServer {
        public static void main(String[] args) throws IOException {
            // 创建 server socket
            ServerSocket server  = new ServerSocket(9000);
            // 获取客户端连接
            Socket socket = server.accept();
            // 获取输入 IO流对象
            InputStream is = socket.getInputStream();
            // 读取 数据
            byte[] bytes = new byte[1024];
            int dataLen = is.read(bytes);
            System.out.println("来自客户端的消息: " + new String(bytes, 0, dataLen));
            // 发送数据
            OutputStream os = socket.getOutputStream();
            os.write("收到了".getBytes("UTF-8"));
            os.flush();
    
            //释放资源
            socket.close();
            server.close();
        }
    }

    client

    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    
    
    public class TCPClient {
        public static void main(String[] args) throws IOException {
            // 创建 socket, 这里就连接服务器的地址和端口了
            Socket socket  = new Socket("localhost", 9000);
            // 获取输出 IO流 对象
            OutputStream os = socket.getOutputStream();
            // 写入 IO 流,  发送到服务端
            os.write("hello world".getBytes("UTF-8"));
            os.flush();
            System.out.println("信息发送成功");
    
            //接收服务端的信息
            InputStream is = socket.getInputStream();
            byte[] bytes = new byte[1024];
            int dataLen = is.read(bytes);
            System.out.println("来自服务端的响应: " + new String(bytes, 0, dataLen));
    
            //释放资源
            socket.close();
        }
    }

    文件传输案例

    把桌面上的文件由客户端传给服务端, 然后服务端改个名字保存到桌面

    server

    import java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class TCPServer {
        public static void main(String[] args) throws IOException {
            // 创建 server socket
            ServerSocket server  = new ServerSocket(9000);
            // 获取客户端连接
            Socket socket = server.accept();
            // 获取输入 IO流对象
            InputStream is = socket.getInputStream();
            // 创建文件 IO输出流, 写到本地
            File f = new File("C:\Users\chenkai\Desktop");
            FileOutputStream fos = new FileOutputStream(f.getAbsoluteFile() + "\test2.jpg");
            // 读取 socket 数据, 写到文件输入流
            int len = 0;
            byte[] bytes = new byte[1024];
            while ((len = is.read(bytes))!=-1){
                fos.write(bytes, 0, len);
            }
    
            // 文件写入完成, 告诉客户端
            OutputStream os = socket.getOutputStream();
            os.write("文件上传完成".getBytes("UTF-8"));
            System.out.println("文件写入完成");
    
            //释放资源
            fos.close();
            socket.close();
            server.close();
        }
    }

    client

    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    
    
    public class TCPClient {
        public static void main(String[] args) throws IOException, IOException {
            // 创建 socket, 这里就连接服务器的地址和端口了
            Socket socket  = new Socket("localhost", 9000);
            // 获取输出 IO流 对象
            OutputStream os = socket.getOutputStream();
            // 获取文件输入流
            FileInputStream fis = new FileInputStream("C:\Users\chenkai\Desktop\test.jpg");
            //
            int len = 0;
            byte[] bytes = new byte[1024];
            while ((len = fis.read(bytes)) != -1) {
                // 写入 IO 流,  发送到服务端
                os.write(bytes);
            }
            // 告诉服务端, 文件写入完成
            socket.shutdownOutput();
            System.out.println("文件上传完成");
    
            //接收服务端的信息
            InputStream is = socket.getInputStream();
            while ((len = is.read(bytes)) != -1) {
                System.out.println("来自服务端的响应: " + new String(bytes,0,len, "UTF-8"));
            }
    
            //释放资源
            fis.close();
            socket.close();
        }
    }

    模拟BS结构服务器分析

    浏览器向TCP服务器发送请求, 服务器返回一张图片给浏览器

    import java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class HTTPServer {
        public static void main(String[] args) throws IOException {
            // 创建 server socket
            ServerSocket server  = new ServerSocket(9000);
            while(true) {
                // 获取客户端连接
                Socket socket = server.accept();
                // 获取输入 IO流对象
                InputStream is = socket.getInputStream();
                // 读取 socket 数据
        //        int len = 0;
        //        byte[] bytes = new byte[1024];
        //        while ((len = is.read(bytes))!=-1){
        //            System.out.println(new String(bytes, 0, len));
        //        }
                BufferedReader br = new BufferedReader(new InputStreamReader(is));
                String firstLine = br.readLine();
                String fileName = firstLine.split(" ")[1].substring(1);
                System.out.println("C:\" + fileName.replace("/", "\"));
                fileName = "C:\" + fileName.replace("/", "\");
                // 读取本地文件
    //            FileInputStream fis = new FileInputStream("C:\Users\chenkai\Desktop\test.jpg");
                FileInputStream fis = new FileInputStream(fileName);
                // 将一张图片回写给浏览器
                OutputStream os = socket.getOutputStream();
                os.write("HTTP/1.1 200 OK
    ".getBytes("UTF-8"));
                os.write("Content-Type: image/jpg
    ".getBytes("UTF-8"));
                os.write("
    ".getBytes("UTF-8"));
                //
                int len = 0;
                byte[] bytes = new byte[1024];
                while ((len = fis.read(bytes)) != -1) {
                    os.write(bytes, 0, len);
                }
    
                //释放资源
                br.close();
                fis.close();
                socket.close();
            }
            //server.close();
        }
    }

    ending ~ 

    每天都要遇到更好的自己.
  • 相关阅读:
    go语言的grpc安装记录
    MySQL1:客户端/服务器架构
    设计模式
    乐观锁与悲观锁的选择
    compareAndSwapObject 产生ABD原因
    wangEditor
    ckeditor4学习
    git公司远程提交
    java面试题总结
    基本数据类型和包装类
  • 原文地址:https://www.cnblogs.com/kaichenkai/p/11821995.html
Copyright © 2011-2022 走看看