6 / 100 SEO Score

  上周经理突然问了我要干嘛,我当时有点懵,后来问的是我继续搞开发还是做个测试售后,然后我说还是想搞开发,这周貌似是答应了我让我继续搞开发,复工第一件事就是云备份数据,业务其实不难理解,就是实现起来我有点举头无措,然后自己深入的了解,反转的在同事和师父之间徘徊询问,大概明白了自己的第一步是啥:用java socket打通通信,进行取数据。有点小心得,赶紧过来记下。

Socket概述

  Java的网络编程主要涉及到的内容是Socket编程。Socket,套接字,就是两台主机之间逻辑连接的端点。TCP/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据。Socket是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议、本地主机的IP地址、本地进程的协议端口、远程主机的IP地址、远程进程的协议端口。

  应用层通过传输层进行数据通信时,TCP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要通过同一个TCP协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了套接字(Socket)接口。应用层可以和传输层通过Socket接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。

  Socket,实际上是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。实际上,Socket跟TCP/IP协议没有必然的关系,Socket编程接口在设计的时候,就希望也能适应其他的网络协议。所以说,Socket的出现,只是使得程序员更方便地使用TCP/IP协议栈而已,是对TCP/IP协议的抽象,从而形成了我们知道的一些最基本的函数接口,比如create、listen、accept、send、read和write等等。网络有一段关于socket和TCP/IP协议关系的说法比较容易理解:

  “TCP/IP只是一个协议栈,就像操作系统的运行机制一样,必须要具体实现,同时还要提供对外的操作接口。这个就像操作系统会提供标准的编程接口,比如win32编程接口一样,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口。”

  实际上,传输层的TCP是基于网络层的IP协议的,而应用层的HTTP协议又是基于传输层的TCP协议的,而Socket本身不算是协议,就像上面所说,它只是提供了一个针对TCP或者UDP编程的接口。socket是对端口通信开发的工具,它要更底层一些。

Socket整体流程

  Socket编程主要涉及到客户端和服务端两个方面,首先是在服务器端创建一个服务器套接字(ServerSocket),并把它附加到一个端口上,服务器从这个端口监听连接。端口号的范围是0到65536,但是0到1024是为特权服务保留的端口号,我们可以选择任意一个当前没有被其他进程使用的端口。

  客户端请求与服务器进行连接的时候,根据服务器的域名或者IP地址,加上端口号,打开一个套接字。当服务器接受连接后,服务器和客户端之间的通信就像输入输出流一样进行操作。
然后说了那么多,我们开始进行一个实例吧。

实例:

服务端

/**
 *  time:2020/3/31
 *  简介:服务端
 */

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerSocketDemo {
    public static void main(String[] args) throws IOException {
        //端口号
        int port = 7000;
        //在端口上创建一个服务器套接字
        ServerSocket serverSocket = new ServerSocket(port);
        //监听来自客户端的连接
        Socket socket = serverSocket.accept();
        System.out.println(socket);

        DataInputStream dis = new DataInputStream(new BufferedInputStream(socket.getInputStream()));

        DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));

        do{
            double length = dis.readDouble();
            System.out.println("服务器收到的数据长度为: " + length);
            double result = length * length;
            dos.writeDouble(result);
            dos.flush();
        } while (dis.readInt() != 0);

        socket.close();
        serverSocket.close();
    }
}

客户端

/**
 *  time:2020/3/31
 *  简介:客户端
 */

import java.io.*;
import java.net.Socket;
import java.util.Scanner;


public class ClientSocketDemo {
    public static void main(String[] args) throws IOException {
        int port = 7000;
        String host = "localhost";
        //创建一个套接字并将其连接到指定端口
        Socket socket = new Socket(host,port);

        DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));

        DataInputStream dis = new DataInputStream(new BufferedInputStream(socket.getInputStream()));

        Scanner sc = new Scanner(System.in);

        boolean flag = false;

        while (!flag){
            System.out.println("请输入正方形的边长:");
            double length = sc.nextDouble();

            dos.writeDouble(length);
            dos.flush();

            double area = dis.readDouble();
            System.out.println("服务器返回的面积为: " + area);

            while (true){
                System.out.println("继续计算?(Y/N)");
                String str = sc.next();

                if(str.equalsIgnoreCase("N")){
                    dos.writeInt(0);
                    dos.flush();
                    flag = true;
                    break;
                }else if(str.equalsIgnoreCase("Y")){
                    dos.writeInt(1);
                    dos.flush();
                    break;
                }
            }
        }
        socket.close();
    }

二十三年文の博客创始人