深入Socket-初探Socket

版权声明:转载需声明本人出品 https://blog.csdn.net/weixin_40288381/article/details/88605190

什么是Socket

  • 简单来说是IP地址与端口的结合协议
  • 一种地址与端口的结合描述协议
  • TCP/IP协议的相关API的总称;是网络API的集合实现
  • 涵盖了Stream Socket/Datagram Socket

Socket的作用与组成

  • 在网络传输中用于唯一标示两个端点之间的链接(端点:IP+Port)
  • 组成的4个要素:客户端地址,客户端端口,服务器地址,服务端端口
    在这里插入图片描述

Socket之TCP

  • TCP是面向连接的通信协议
  • 通过三次握手建立连接,通讯完成时要拆除连接
  • 由于TCP是面向连接的所以只能用于端到端的通讯,换句话说一个端口连接另一个端口时就无法连接其他端口
TCP传输

在这里插入图片描述

Socket之UDP

  • UDP是面向无连接的通信协议
  • UDP数据包含目的端口号和源端口号信息
  • 由于通讯不需要连接,所以可以实现广播放送,并不局限于端到端
UDP传输

在这里插入图片描述
UDP只负责发送数据,并不需要反馈去确保数据是否成功发送


小栗子

客户端

public class Client {
    public Client() {
    }

    public static void main(String[] args) throws IOException {
        Socket socket = new Socket();
        socket.setSoTimeout(3000);
		
		//客户端建立与服务器的连接
        socket.connect(new InetSocketAddress(Inet4Address.getLocalHost(), 2000), 3000);
        System.out.println("已发起服务器连接,并进入后续流程~");
        System.out.println("客户端信息:" + socket.getLocalAddress() + " P:" + socket.getLocalPort());
        System.out.println("服务器信息:" + socket.getInetAddress() + " P:" + socket.getPort());

        try {
            todo(socket);
        } catch (Exception var3) {
            System.out.println("异常关闭");
        }

        socket.close();
        System.out.println("客户端已退出~");
    }

    private static void todo(Socket client) throws IOException {
    	//将输入流包装成缓冲字符流
        InputStream in = System.in;
        BufferedReader input = new BufferedReader(new InputStreamReader(in));
		
		//获取客户端的输出流并包装成打印流
        OutputStream outputStream = client.getOutputStream();
        PrintStream socketPrintStream = new PrintStream(outputStream);
		
		//获取客户端的输入流
        InputStream inputStream = client.getInputStream();
        BufferedReader socketBufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        boolean flag = true;

        do {
        	//获取键盘输入流
            String str = input.readLine();
            //将输入打印给服务器端
            socketPrintStream.println(str);
            String echo = socketBufferedReader.readLine();
            if("bye".equalsIgnoreCase(echo)) {
                flag = false;
            } else {
                System.out.println(echo);
            }
        } while(flag);

        socketPrintStream.close();
        socketBufferedReader.close();
    }
}

服务器端

public class Server {
    public Server() {
    }

    public static void main(String[] args) throws IOException {
    	//服务器监听本机的2000断开
        ServerSocket server = new ServerSocket(2000);
        System.out.println("服务器准备就绪~");
        System.out.println("服务器信息:" + server.getInetAddress() + " P:" + server.getLocalPort());

        while(true) {
        	//获取客户端
            Socket client = server.accept();
            //启动异步线程,处理多客户端
            Server.ClientHandler clientHandler = new Server.ClientHandler(client);
            clientHandler.start();
        }
    }

    private static class ClientHandler extends Thread {
        private Socket socket;
        private boolean flag = true;

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

        public void run() {
            super.run();
            System.out.println("新客户端连接:" + this.socket.getInetAddress() + " P:" + this.socket.getPort());

            try {
            	//获取客户端的输出流
                PrintStream e = new PrintStream(this.socket.getOutputStream());
                BufferedReader socketInput = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));

                do {
                	//获取从客户端键盘输入的流,这里是客户端输出到服务器端
                    String str = socketInput.readLine();
                    if("bye".equalsIgnoreCase(str)) {
                        this.flag = false;
                        e.println("bye");
                    } else {
                        System.out.println(str);
                        e.println("回送:" + str.length());
                    }
                } while(this.flag);

                socketInput.close();
                e.close();
            } catch (Exception var12) {
                System.out.println("连接异常断开");
            } finally {
                try {
                    this.socket.close();
                } catch (IOException var11) {
                    var11.printStackTrace();
                }

            }

            System.out.println("客户端已退出:" + this.socket.getInetAddress() + " P:" + this.socket.getPort());
        }
    }
}

报文
  • 报文段在TCP/IP协议网络传输过程,起着路由导航作用
  • 用以查询各个网络路由网段,IP地址,交换协议等IP数据包
  • 报文段充当整个TCP/IP协议数据包的导航路由功能
  • 报文在传输过程中会不断地封装成分组,包,帧来传输
  • 封装方式就是添加一些控制信息组成的首部,即报文头
Mac地址

Mac-Media Access Control-即媒体访问控制,或称为物理地址,硬件地址,用来定义网络设备的位置。

猜你喜欢

转载自blog.csdn.net/weixin_40288381/article/details/88605190