网络基本原理-Socket编程(2)

TCP 协议下的 C/S

UDP : 不可靠的、无连接的、发送/接受数据时,是以数据报为单位的

TCP: 可靠的、有链接的、发送数据时是以数据流的形式

可靠/不可靠 : 可靠并不能代表就一定能通过网络发送成功。而是发送的数据尽可能的保证成功,即使失败了,发送方也有感知

在这里插入图片描述


面向字节流: 一个连接可以只传递一组 请求-响应:

发送“你好\r\n”
接受是 “你”“好””\r“"\n",当收到EOS时,请求读取结束了

一个连接可以传递多组 请求-响应
发送”请求1请求2“
接收时 “请” “求1” “请” “求2”

如何把多个请求分开?

  1. 先长度,再数据
  2. 固定长度
  3. 特殊字符分割

网络连接时序图

在这里插入图片描述
值得强调的是,在这种情况下,有多个客户端且一个客户端没有发送给服务器请求,那么别的客户端就不会收到响应,发生阻塞
这种情况下就要使用多线程

import java.util.*;
import java.net.*;
import java.io.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Server {
    private static class ServiceMan extends Thread {
        private final Socket socket;

        ServiceMan(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            try {
                // 获取输入流
                InputStream is = socket.getInputStream();
                // 封装成 Scanner
                Scanner scanner = new Scanner(is, "UTF-8");
                // 使用 \r\n 进行分割的方式,读取一个请求

                // 等着第一个 Client 发送请求
                String request = scanner.nextLine();    // nextLine() 把 \r\n 已经去掉
                System.out.println("收到请求: " + request);

                // 业务处理
                String response = request;

                // 发送响应,也许要使用 \r\n 跟在后边,进行分割
                OutputStream os = socket.getOutputStream();
                // 封装成 PrintWriter
                PrintWriter writer = new PrintWriter(
                        new OutputStreamWriter(os, "UTF-8")
                );
                // 发送响应
                writer.println(response);   // println 会帮我们在后边增加 \r\n
                writer.flush();

                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws IOException {
        // 开一家店
        ServerSocket serverSocket = new ServerSocket(9898);
        ExecutorService threadPool = Executors.newFixedThreadPool(20);

        // 循环处理业务
        // 主线程只负责接待 —— 连接连接的过程
        while (true) {
            Socket socket = serverSocket.accept();  // 虽然有 4 个Client 连接,socket 代表的是第一个Client
            /*
            // 所有业务处理的过程,交给线程去处理
            new ServiceMan(socket).start();
             */

            // 各个线程之间,没有数据共享(主线程和工作线程之间共享 socket)
            // 所以天生是线程安全的
            threadPool.execute(new ServiceMan(socket));
        }
    }
}
import java.util.*;
import java.io.*;
import java.net.*;
import java.util.concurrent.TimeUnit;

public class Client {
    public static void main(String[] args) throws IOException, InterruptedException {
        Socket socket = new Socket("127.0.0.1", 9898);

        Scanner console = new Scanner(System.in);
        System.out.print("请输入请求> ");
        String request = console.nextLine();

        OutputStream os = socket.getOutputStream();
        PrintWriter writer = new PrintWriter(
            new OutputStreamWriter(os, "UTF-8")
        );
        writer.println(request);
        writer.flush();

        InputStream is = socket.getInputStream();
        Scanner scanner = new Scanner(is, "UTF-8");

        String response = scanner.nextLine();   // 对象没有响应,就一直等
        System.out.println(response);

        socket.close();
    }
}

HTTP协议

重点协议——应用层上非常广泛的一组HTTPS

Hyper Text Transfer Protocol : 超文本传输协议

1.0/1.1版本的时候,HTTP还是建立在TCP基础上 —— HTTP协议需要可靠性作为基础的
http协议的标准端口: 80


URL —— Unique Resource Location

是在互联网上唯一表示一个资源

格式:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值