Socket 攻略

112 阅读4分钟

攻略大全

1. 粘贴攻略

1.1 计算机网络体系结构

1.1.1 简介

定义:计算机网络的各层+其协议的组合

作用:定义该计算机网络所能完成的功能

1.1.2 结构介绍

计算机网络体系结构分为3种:OSI体系结构、TCP / IP体系结构、五层体系结构

OSI体系结构:概念清楚、理念完整,但是复杂且不实用

TCP/IP体系结构:包含了一系列构成互联网基础的网络协议,是Internet的核心协议,被广泛应用于局域网和广域网。

五层体系结构:融合了OSI与TCP/IP的体系结构,目的是为了学习与讲解计算机原理。

image.png

1.1.2.1 详解TCP/IP

944365-429360cb75ec4cef.png

944365-67e745b520aaf63b.png

1.1.2.2 详解OSI

944365-528b5fa6679a99c6.png

944365-5278b003549ed53a.png

1.2 Socket

1.2.1 简介

即套接字,是应用层 与 TCP/IP 协议族通信的中间软件抽象层,表现为一个封装了 TCP / IP协议族 的编程接口(API)。

944365-1a92e10c6c694d0f.png

  1. Socket不是一种协议,而是一个编程调用接口(API),属于传输层(主要解决数据如何在网络中传输)
  2. 即:通过Socket,我们才能在Andorid平台上通过 TCP/IP协议进行开发
  3. 对用户来说,只需调用Socket去组织数据,以符合指定的协议,即可通信
  • 成对出现,一对套接字:Socket = {(IP地址1:PORT端口号),(IP地址2:PORT端口号)}

  • 一个 Socket 实例,唯一代表一个主机上的一个应用程序的通信链路

1.2.2 建立Socket连接过程

image.png

1.2.3 原理

Socket的使用类型主要有两种:

  • 流套接字(StreamSocket) :基于 TCP协议,采用 流的方式 提供可靠的字节流服务
  • 数据报套接字(DatagramSocket):基于 UDP协议,采用 数据报文 提供数据打包发送的服务

具体原理图如下:

image.png

1.2.4 Socket与Http对比

  • Socket属于传输层,因为 TCP / IP协议属于传输层,解决的是数据如何在网络中传输的问题
  • HTTP协议 属于 应用层,解决的是如何包装数据

由于二者不属于同一层面,所以本来是没有可比性的。但随着发展,默认的Http里封装了下面几层的使用,所以才会出现Socket & HTTP协议的对比(主要是工作方式的不同):

  • Http:采用 请求—响应 方式。
  1. 即建立网络连接后,当 客户端 向 服务器 发送请求后,服务器端才能向客户端返回数据。
  2. 可理解为:是客户端有需要才进行通信
  • Socket:采用 服务器主动发送数据 的方式
  1. 即建立网络连接后,服务器可主动发送消息给客户端,而不需要由客户端向服务器发送请求
  2. 可理解为:是服务器端有需要才进行通信

1.2.5 TCP&Socket实战

服务端

import java.io.*;
import java.net.*;

public class TcpServer {
    public static void main(String[] args) {
        int port = 8080; // 服务器监听端口

        try (ServerSocket serverSocket = new ServerSocket(port)) {
            System.out.println("TCP Server started on port " + port);

            while (true) {
                // 接受客户端连接
                try (Socket clientSocket = serverSocket.accept()) {
                    System.out.println("New client connected: " + clientSocket.getInetAddress());

                    // 获取输入流(接收客户端数据)
                    BufferedReader in = new BufferedReader(
                            new InputStreamReader(clientSocket.getInputStream()));
                    // 获取输出流(发送数据到客户端)
                    PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);

                    // 读取客户端发送的消息
                    String message = in.readLine();
                    System.out.println("Received from client: " + message);

                    // 将消息回显给客户端
                    out.println("Echo: " + message);
                } catch (IOException e) {
                    System.out.println("Error handling client: " + e.getMessage());
                }
            }
        } catch (IOException e) {
            System.out.println("Server error: " + e.getMessage());
        }
    }
}

客户端

import java.io.*;
import java.net.*;

public class TcpClient {
    public static void main(String[] args) {
        String hostname = "localhost"; // 服务器地址
        int port = 8080; // 服务器端口

        try (
                Socket socket = new Socket(hostname, port);
                // 创建输出流(发送数据到服务器)
                PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
                // 创建输入流(接收服务器返回的数据)
                BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                // 从控制台读取用户输入
                BufferedReader consoleInput = new BufferedReader(new InputStreamReader(System.in))
        ) {
            System.out.println("Connected to TCP server at " + hostname + ":" + port);

            // 获取用户输入
            System.out.print("Enter message to send: ");
            String userInput = consoleInput.readLine();

            // 发送消息到服务器
            out.println(userInput);

            // 接收服务器的回显消息
            String response = in.readLine();
            System.out.println("Server response: " + response);

        } catch (IOException e) {
            System.out.println("Client error: " + e.getMessage());
        }
    }
}

1.2.6 UDP&Socket实战

服务端

import java.net.*;

public class UdpServer {
    public static void main(String[] args) {
        int port = 8081; // 服务器监听端口

        try (DatagramSocket socket = new DatagramSocket(port)) {
            System.out.println("UDP Server started on port " + port);

            byte[] buffer = new byte[1024]; // 接收缓冲区

            while (true) {
                // 创建数据包用于接收客户端数据
                DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
                socket.receive(packet); // 接收数据

                // 从数据包中提取消息
                String message = new String(packet.getData(), 0, packet.getLength());
                System.out.println("Received from client: " + message + 
                        " [from " + packet.getAddress() + ":" + packet.getPort() + "]");

                // 可选:发送响应给客户端
                String response = "Received: " + message;
                byte[] responseData = response.getBytes();
                DatagramPacket responsePacket = new DatagramPacket(
                        responseData, responseData.length, packet.getAddress(), packet.getPort());
                socket.send(responsePacket);
            }
        } catch (SocketException e) {
            System.out.println("Socket error: " + e.getMessage());
        } catch (IOException e) {
            System.out.println("IO error: " + e.getMessage());
        }
    }
}

客户端

import java.net.*;
import java.io.*;

public class UdpClient {
    public static void main(String[] args) {
        String hostname = "localhost"; // 服务器地址
        int port = 8081; // 服务器端口

        try (DatagramSocket socket = new DatagramSocket()) {
            InetAddress address = InetAddress.getByName(hostname);
            System.out.println("UDP Client started");

            // 从控制台读取用户输入
            BufferedReader consoleInput = new BufferedReader(new InputStreamReader(System.in));
            System.out.print("Enter message to send: ");
            String message = consoleInput.readLine();

            // 将消息转换为字节并发送
            byte[] sendData = message.getBytes();
            DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, address, port);
            socket.send(sendPacket);
            System.out.println("Message sent to server");

            // 接收服务器响应
            byte[] buffer = new byte[1024];
            DatagramPacket receivePacket = new DatagramPacket(buffer, buffer.length);
            socket.receive(receivePacket);
            String response = new String(receivePacket.getData(), 0, receivePacket.getLength());
            System.out.println("Server response: " + response);

        } catch (UnknownHostException e) {
            System.out.println("Unknown host: " + e.getMessage());
        } catch (IOException e) {
            System.out.println("IO error: " + e.getMessage());
        }
    }
}

2. 造火箭攻略

3. 拧螺丝攻略

4. 复制攻略

4.1 《计算机网络》

4.2 《HTTP权威指南》