【有书共读】《疯狂JAVA讲义》读书笔记17

这次是java疯狂讲义第17章,是关于网络线程的,我有以下几点总结:

Socket 编程

套接字使用TCP提供了两台计算机之间的通信机制。 客户端程序创建一个套接字,并尝试连接服务器的套接字。

当连接建立时,服务器会创建一个 Socket 对象。客户端和服务器现在可以通过对 Socket 对象的写入和读取来进行通信。

java.net.Socket 类代表一个套接字,并且 java.net.ServerSocket 类为服务器程序提供了一种来监听客户端,并与他们建立连接的机制。

以下步骤在两台计算机之间使用套接字建立TCP连接时会出现:

  • 服务器实例化一个 ServerSocket 对象,表示通过服务器上的端口通信。

  • 服务器调用 ServerSocket 类的 accept() 方法,该方法将一直等待,直到客户端连接到服务器上给定的端口。

  • 服务器正在等待时,一个客户端实例化一个 Socket 对象,指定服务器名称和端口号来请求连接。

  • Socket 类的构造函数试图将客户端连接到指定的服务器和端口号。如果通信被建立,则在客户端创建一个 Socket 对象能够与服务器进行通信。

  • 在服务器端,accept() 方法返回服务器上一个新的 socket 引用,该 socket 连接到客户端的 socket。

连接建立后,通过使用 I/O 流在进行通信,每一个socket都有一个输出流和一个输入流,客户端的输出流连接到服务器端的输入流,而客户端的输入流连接到服务器端的输出流。

TCP 是一个双向的通信协议,因此数据可以通过两个数据流在同一时间发送.以下是一些类提供的一套完整的有用的方法来实现 socket


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

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




下面是一个客户端和服务器端进行数据交互的简单例子,客户端输入正方形的边长,服务器端接收到后计算面积并返回给客户端,通过这个例子可以初步对Socket编程有个把握。

服务器端
public class SocketServer {

    public static void main(String[] args) throws IOException {

        // 端口号
        int port = 7000;
        // 在端口上创建一个服务器套接字
        ServerSocket serverSocket = new ServerSocket(port);
        // 监听来自客户端的连接
        Socket socket = serverSocket.accept();

        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();
    }
}
客户端
public class SocketClient {

    public static void main(String[] args) throws UnknownHostException, IOException {

        int port = 7000;

        String host = "localhost";

        // 创建一个套接字并将其连接到指定端口号
        Socket socket = new Socket(host, port);

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

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

        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();
    }
}


IP地址分为5类ABCDE,

A类:10.0.0.0~10.255.255.255;

B类:172.16.0.0~172.31.255.255;

C类:192.168.0.0~192.168.255.255

公认端口:0~1023;

注册端口:1024~49151,应用程序通常使用这些端口;

动态和/或私有端口:49152~65535,应用程序一般不会主动使用这些端口。

使用InetAddress:InetAddress没有提供构造器,而是提供两个静态方法来获取InetAddress实例:①getByName(String host):根据主机获取对应的InetAddress对象;②getByAddress(byte[] addr):根据原始IP地址获取对应的InetAddress对象。InetAddress还提供了3个方法来获取InetAddress实例对应的IP地址和主机名:①String getCanoicalHostName():获取此IP地址的全限定域名;②String getHostAddress():返回此InetAddress实例对应的IP地址和字符串;③String getHostName():获取此IP地址的主机名。InetAddress还提供了一个getLocalHost()方法来获取本机IP地址和InetAddress实例。InetAddress还提供了isReachable()方法来测试是否可以到达该地址。

InetAddress ip=InetAddress.getByName("www.crazyit.org");

System.out.println("是否可以到达某网站:"+ip.isReachable(2000));

System.out.println(ip.getHostAddress());

InetAddress local=InetAddress.getByAddress(new byte[] {127,0,0,1});

System.out.println("本机是否可达:"+local.isReachable(2000));

System.out.println(local.getCanonicalHostName());

输出:是否可以到达某网站:true    222.73.85.205    本机是否可达:true    127.0.0.1

使用ServerSocket创建TCP服务端:ServerSocket对象用于监听来自客户端的Socket请求,如果没有连接,将一直处于等待状态:①Socket accept():如果接收到一个客户端Socket请求,将返回一个与客户端Socket对应的Socket。ServerSocket提供了如下几个构造器:①Socket accept(int port):用指定端口port来创建一个ServerSocket,有效值0-65535。当ServerSocket使用完毕后,应使用close方法来关闭该ServerSocket。

IP地址是:127.0.0.1一般代表本机的IP地址。Socket提供了2个方法来获取输入流和输出流:InputStream getInputStream和OutputStream getOutputStream。Socket对象提供了一个setSoTimeout(int millis)的超时连接。

 

Socket通信例子

客户端:Socket conToServer=new Socket("localhost",5500);

//数据输入流:

DataInputStream inFromSer=new DataInputStream(conToServer.getInputStream());

//数据输出流:

DataOutputStream outToSer=new DataOutputStream(conToServer.getOutputStream());

服务端:ServerSocket serSock=new ServerSocket(5500);

//侦听来自客户端的连接请求 

Socket conFromCli=serSock.accept();

//接收数据:

DataInputStream inFromCli=new DataInputStream(conFromCli.getInputStream());

  

使用DatagramSocket发送、接收数据:DatagramSocket构造器有3个:①DatagramSocket()无参数构造器表示绑定到本机默认IP地址、本机的所有可以用的随机端口;②DatagramSocket(int port)③DatagramSocket(int port,InetAddress add),都很好理解。通过如下两个方法来接收和发送数据:receive(DatagramSocket p); send(DatagramSocket p)。

 

使用***服务器:

***服务器的功能就是***用户去取得网络信息,浏览器不是直接去向Web服务器发送请求,而是向***服务器发送请求。***服务器有2个好处:①突破自身IP限制,对外隐藏自身IP地址,包括访问国外受限站点,访问国内特定单位、团体的内部资源;②提高访问速度,***服务器提供缓存功能可以避免用户直接访问远程主机,从而提高客户端的访问速度。

 



#笔记##读书笔记#
全部评论

相关推荐

牛客339922477号:都不用reverse,直接-1。一行。啥送分题
点赞 评论 收藏
分享
点赞 评论 收藏
分享
1 收藏 评论
分享
牛客网
牛客企业服务