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 ~ 

    每天都要遇到更好的自己.
  • 相关阅读:
    Intent
    What should we do next in general after collecting relevant data
    NOTE FOR Secure Friend Discovery in Mobile Social Networks
    missing pcap.h
    after building Android Source code
    plot point(one column)
    When talking to someone else, don't infer that is has been talked with others at first. It may bring repulsion to the person who is talking with you.
    进程基本知识
    Python input和raw_input的区别
    强制 code review:reviewboard+svn 的方案
  • 原文地址:https://www.cnblogs.com/kaichenkai/p/11821995.html
Copyright © 2011-2022 走看看