Java网络通信

目录

前言

一、网络通信的概述

二、网络通信的三要素

2.1 IP地址

2.2 端口号

2.3 协议

三、UDP

3.1 UDP通信-快速入门 

3.2 UDP通信-多发多收

四、TCP

4.1 TCP通信-快速入门

4.2 TCP通信之-客户端开发

4.3TCP通信之-服务器端开发

4.4 TCP通信-多发多收

4.5 TCP通信-支持与多个客户端同时通信

4.6 TCP通信-综合案例

4.6.1 群聊实现

4.6.2 实现一个简易版的BS架构

4.6.2.1 拓展知识:每次请求都开一个新线程,到底好不好?


前言

java网络编程笔记复盘【完】,后续更细在java高级技术


一、网络通信的概述

1. 什么是网络编程?
可以让设备中的程序与网络上其他设备中的程序进行数据交互(实现网络通信的)

Java提供了哪些网络编程的解决方案:
java.net.*包下提供了网络编程的解决方案

基本的通信架构
基本的通信架构有2种形式:CS架构(Client客户端/Server服务端)、BS架构(Browser浏览器/Server服务端)

二、网络通信的三要素

2.1 IP地址

  • IP(InternetProtocol):全称”互联网协议地址”,是分配给上网设备的唯一标志。【设备在网络中的地址,是唯一的标识。(可以理解为设备在网络中的身份证号码)】
  • IP地址有两种形式:IPV4、IPV6

IPv6地址

  • IPv6:共128位,号称可以为地球每一粒沙子编号,
  • IPV6分成8段表示,每段每四位编码成一个十六进制位表示,数之间用冒号(:)分开

 IP域名

公网IP,内网IP 

  • 公网IP:是可以连接互联网的IP地址;内网IP:也叫局域网IP,只能组织机构内部使用
  • 192.168.开头的就是常见的局域网地址,范围即为192.168.0.0--192.168.255.255,专门为组织机构内部使用。

特殊IP地址

127.0.0.1、localhost:代表本机IP,只会寻找当前所在的主机

IP常用命令:

  • ipconfig:查看本机IP地址。
  • pingIP地址:检查网络是否连通。

 InetAddress
代表IP地址

 InetAddressTest.class

package com.itheima.d1_ip;

import java.net.InetAddress;

public class InetAddressTest {
    public static void main(String[] args) throws Exception {
        //1、获取本机IP地址对象的
        InetAddress ip1 = InetAddress.getLocalHost();
        System.out.println(ip1.getHostName());
        System.out.println(ip1.getHostAddress());

        //2、获取指定IP或着域名的IP地址对象
        InetAddress ip2 = InetAddress.getByName("www.bilibili.com");
        System.out.println(ip2.getHostName());
        System.out.println(ip2.getHostAddress());

        //相当于ping命令
        System.out.println(ip2.isReachable(6000));
    }
}

2.2 端口号

标记正在计算机设备上运行的应用程序的,被规定为一个16位的二进制,范围是0~65535

分类

  • 周知端口:0~1023,被预先定义的知名应用占用(如:HTTP占用 80,FTP占用21)
  • 注册端口:1024~49151,分配给用户进程或某些应用程序
  • 动态端口:49152到65535,之所以称为动态端口,是因为它 一般不固定分配某种进程,而是动态分配。

注意:我们自己开发的程序一般选择使用注册端口,且一个设备中不能出现两个程序的端口号一样,否则出错。

2.3 协议

网络上通信的设备,事先规定的连接规则,以及传输数据的规则被称为网络通信协议。

开放式网络互联标准:OSI网络参考模型

  • OSI网络参考模型:全球网络互联标准
  • TCP/IP网络模型:事实上的国际标准

传输层的2个通信协议

UDP(User Datagram Protocol):用户数据报协议;TCP(Transmission ControlProtocol):传输控制协议

UDP协议(通信效率高)

  • 特点:无连接、不可靠通信。
  • 不事先建立连接,数据按照包发,一包数据包含:自己的IP、程序端口,目的地IP、程序端口和数据(限制在64KB内)等。
  • 发送方不管对方是否在线,数据在中间丢失也不管,如果接收方收到数据也不返回确认,故是不可靠的

TCP协议(通信效率相对不高)

  • 特点:面向连接、可靠通信。
  • TCP的最终目的:要保证在不可靠的信道上实现可靠的传输
  • TCP主要有三个步骤实现可靠传输:三次握手建立连接,传输数据进行确认,四次挥手断开连接。

传输数据会进行确认,以保证数据传输的可靠性 

三、UDP

3.1 UDP通信-快速入门 

  • 特点:无连接、不可靠通信。
  • 不事先建立连接;发送端每次把要发送的数据(限制在64KB内)、接收端IP、等信息封装成一个数据包,发出去就不管了。
  • Java提供了一个java.net.DatagramSocket类来实现UDP通信

DatagramSocket:用于创建客户端、服务端

 DatagramPacket:创建数据包

 Client.class

package com.itheima.d2_upd1;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class Client {
    public static void main(String[] args) throws Exception {
        //1、创建客户端对象(发非菜出去的人)
        DatagramSocket socket=new DatagramSocket();

        //2、创建数据包对象封装要发出去的数据(创建一个韭菜盘子)
        //public DatagramPacket(byte buf[],int length,InetAddress address,int port)
        //参数一:封装要发出去的数据。
        //参数二:发送出去的数据大小(字节个数)
        //参数三:服务端的IP地址(找到服务端主机)
        //参数四:服务端程序的端口。
        byte[] bytes = "我是一个客户端".getBytes();
        DatagramPacket packet=new DatagramPacket(bytes,bytes.length, InetAddress.getLocalHost(),6666);

        //3、开始正式发送这个数据包的数据出去了
        socket.send(packet);

        System.out.println("客户端数据发送完毕");
        socket.close();//释放资源

    }
}

 Server.class

package com.itheima.d2_upd1;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class Server {
    public static void main(String[] args) throws Exception {
        System.out.println("服务端启动!");
        //1、创建一个雁务端对象(创建一个接韭菜的人),注册端口
        DatagramSocket socket = new DatagramSocket(6666);

        // 2、创建一个数据包对象,用于接收数据的(创建一个韭菜盘子)
        byte[] buffer = new byte[1024 * 64];//64KB
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

        //3、开始正式使用数据包来接收客户端发来的数据
        socket.receive(packet);

        //4、从字节数组中,把接收到的数据直接打印出来
        //接收多少就倒出多少
        // 获取本次数据包接收了多少数据
        int length = packet.getLength();
        String rs = new String(buffer, 0, length);
        System.out.println(rs);

        System.out.println(packet.getAddress().getHostAddress());
        System.out.println(packet.getPort());

        socket.close();//释放资源

    }
}

3.2 UDP通信-多发多收

Client.class

package com.itheima.d3_udp2;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;

public class Client {
    public static void main(String[] args) throws Exception {
        //1、创建客户端对象(发非菜出去的人)
        DatagramSocket socket = new DatagramSocket();

        //2、创建数据包对象封装要发出去的数据(创建一个韭菜盘子)
        //public DatagramPacket(byte buf[],int length,InetAddress address,int port)
        //参数一:封装要发出去的数据。
        //参数二:发送出去的数据大小(字节个数)
        //参数三:服务端的IP地址(找到服务端主机)
        //参数四:服务端程序的端口。
//        byte[] bytes = "我是一个客户端".getBytes();
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("请说");
            String msg = sc.nextLine();
            //一旦发现用户输入的exit命令,就退出客户端
            if ("exit".equals(msg)) {
                System.out.println("欢迎您下次使用,退出成功!");
                socket.close();//释放资源
                break;//退出死循环
            }
            byte[] bytes = msg.getBytes();
            DatagramPacket packet = new DatagramPacket(bytes, bytes.length, InetAddress.getLocalHost(), 6666);

            //3、开始正式发送这个数据包的数据出去了
            socket.send(packet);
        }


    }
}

Server.class 

package com.itheima.d3_udp2;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class Server {
    public static void main(String[] args) throws Exception {
        System.out.println("服务端启动!");
        //1、创建一个雁务端对象(创建一个接韭菜的人),注册端口
        DatagramSocket socket = new DatagramSocket(6666);

        // 2、创建一个数据包对象,用于接收数据的(创建一个韭菜盘子)
        byte[] buffer = new byte[1024 * 64];//64KB
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

        while (true) {
            //3、开始正式使用数据包来接收客户端发来的数据
            socket.receive(packet);

            //4、从字节数组中,把接收到的数据直接打印出来
            //接收多少就倒出多少
            // 获取本次数据包接收了多少数据
            int length = packet.getLength();
            String rs = new String(buffer, 0, length);
            System.out.println(rs);

            System.out.println(packet.getAddress().getHostAddress());
            System.out.println(packet.getPort());
        }
    }
}

如果要使用多个客户端通信的话,在运行设置中

四、TCP

4.1 TCP通信-快速入门

  • 特点:面向连接、可靠通信
  • 通信双方事先会采用“三次握手”方式建立可靠连接,实现端到端的通信;底层能保证数据成功传给服务端
  • Java提供了一个java.net.Socket类来实现TCP通信

 

4.2 TCP通信之-客户端开发

客户端程序就是通过java.net包下的Socket类来实现的

 Client.class

package com.itheima.d4_tcp1;

import java.io.DataOutputStream;
import java.io.OutputStream;
import java.net.Socket;

public class Client {
    public static void main(String[] args) throws Exception {
        //1、创建Socket对象,并同时请求与服务端程序的连接
        Socket socket = new Socket("127.0.0.0",8888);

        //2、从socket通信管道中得到一个字节输出流,用来发数据给服务端程序。
        OutputStream os = socket.getOutputStream();

        //3、把低级的字节输出流包装成数据输出流
        DataOutputStream dos=new DataOutputStream(os);

        // 4、开始写数据出去了
        dos.writeUTF("你好!");
        dos.close();

        socket.close();
    }
}

4.3TCP通信之-服务器端开发

服务端是通过java.net包下的ServerSocket类来实现的

Client.class 

package com.itheima.d4_tcp1;

import java.io.DataOutputStream;
import java.io.OutputStream;
import java.net.Socket;

public class Client {
    public static void main(String[] args) throws Exception {
        //1、创建Socket对象,并同时请求与服务端程序的连接
        Socket socket = new Socket("127.0.0.1",8888);

        //2、从socket通信管道中得到一个字节输出流,用来发数据给服务端程序。
        OutputStream os = socket.getOutputStream();

        //3、把低级的字节输出流包装成数据输出流
        DataOutputStream dos=new DataOutputStream(os);

        // 4、开始写数据出去了
        dos.writeUTF("你好!");
        dos.close();

        socket.close();
    }
}

 Server.class

package com.itheima.d4_tcp1;

import java.io.DataInputStream;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    public static void main(String[] args) throws Exception {
        System.out.println("======服务端启动======");

        //1、创建ServerSocket的对象,同时为服务端注册口。
        ServerSocket serverSocket = new ServerSocket(8888);

        //2、使用serverSocket对象,调用个accept方法,等待客户端的连接请求
        Socket socket = serverSocket.accept();

        //3、从socket迎信管道中得到一个字节输入流。
        InputStream is = socket.getInputStream();

        // 4、把原始的字节输入流包装成数输入流
        DataInputStream dis = new DataInputStream(is);

        //5、使用数据输入流读取客户端发送过来的消息
        String rs = dis.readUTF();
        System.out.println(rs);

        // 其实我们也可以获取客户端的IP地址
        System.out.println(socket.getRemoteSocketAddress());

        dis.close();
        socket.close();

    }
}

4.4 TCP通信-多发多收

Client.class 

package com.itheima.d4_tcp1;

import java.io.DataOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;

public class Client {
    public static void main(String[] args) throws Exception {
        //1、创建Socket对象,并同时请求与服务端程序的连接
        Socket socket = new Socket("127.0.0.1",8888);

        //2、从socket通信管道中得到一个字节输出流,用来发数据给服务端程序。
        OutputStream os = socket.getOutputStream();

        //3、把低级的字节输出流包装成数据输出流
        DataOutputStream dos=new DataOutputStream(os);

        Scanner sc=new Scanner(System.in);
        while (true) {
            System.out.println("请说:");
            String msg = sc.nextLine();
            // 一旦用户输入了exit,就退出客户端程片
            if("exit".equals(msg)){
                System.out.println("欢迎您下您光临!");
                dos.close();
                socket.close();
                break;
            }

            // 4、开始写数据出去了
            dos.writeUTF("你好!");
            dos.flush();
        }

    }
}

 Server.class

package com.itheima.d4_tcp1;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    public static void main(String[] args) throws Exception {
        System.out.println("======服务端启动======");

        //1、创建ServerSocket的对象,同时为服务端注册口。
        ServerSocket serverSocket = new ServerSocket(8888);

        //2、使用serverSocket对象,调用个accept方法,等待客户端的连接请求
        Socket socket = serverSocket.accept();

        //3、从socket迎信管道中得到一个字节输入流。
        InputStream is = socket.getInputStream();

        // 4、把原始的字节输入流包装成数输入流
        DataInputStream dis = new DataInputStream(is);

        while (true) {
            //5、使用数据输入流读取客户端发送过来的消息
            try {
                String rs = dis.readUTF();
                System.out.println(rs);
            } catch (Exception e) {
                System.out.println(socket.getRemoteSocketAddress()+"离线了!");
                dis.close();
                socket.close();
                e.printStackTrace();
            }

            // 其实我们也可以获取客户端的IP地址
            //System.out.println(socket.getRemoteSocketAddress());
        }
    }
}

4.5 TCP通信-支持与多个客户端同时通信

 Client.class

package com.itheima.d5_tcp2;

import java.io.DataOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;

public class Client {
    public static void main(String[] args) throws Exception {
        //1、创建Socket对象,并同时请求与服务端程序的连接
        Socket socket = new Socket("127.0.0.1",8888);

        //2、从socket通信管道中得到一个字节输出流,用来发数据给服务端程序。
        OutputStream os = socket.getOutputStream();

        //3、把低级的字节输出流包装成数据输出流
        DataOutputStream dos=new DataOutputStream(os);

        Scanner sc=new Scanner(System.in);
        while (true) {
            System.out.println("请说:");
            String msg = sc.nextLine();
            // 一旦用户输入了exit,就退出客户端程片
            if("exit".equals(msg)){
                System.out.println("欢迎您下您光临!");
                dos.close();
                socket.close();
                break;
            }

            // 4、开始写数据出去了
            dos.writeUTF(msg);
            dos.flush();
        }
    }
}

Server.class

package com.itheima.d5_tcp2;

import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    public static void main(String[] args) throws Exception {
        System.out.println("======服务端启动======");

        //1、创建ServerSocket的对象,同时为服务端注册口。
        ServerSocket serverSocket = new ServerSocket(8888);

        while (true) {
            //2、使用serverSocket对象,调用个accept方法,等待客户端的连接请求
            Socket socket = serverSocket.accept();

            System.out.print("有人上线了!");
            System.out.println(socket.getRemoteSocketAddress());

            //3、从socket迎信管道中得到一个字节输入流。
            new ServiceReaderThread(socket).start();


        }
    }
}

 ServiceReaderThread.class

package com.itheima.d5_tcp2;

import java.io.DataInputStream;
import java.io.InputStream;
import java.net.Socket;

public class ServiceReaderThread extends Thread {
    private Socket socket;

    public ServiceReaderThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            InputStream is = socket.getInputStream();
            DataInputStream dis = new DataInputStream(is);
            while (true){
                try {
                    String msg = dis.readUTF();
                    System.out.println(msg);
                } catch (Exception e) {
                    System.out.println("有人下线了!"+socket.getRemoteSocketAddress());
                    dis.close();
                    socket.close();
                    break;
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4.6 TCP通信-综合案例

4.6.1 群聊实现

Client.class 

package com.itheima.d6_tcp3;

import java.io.DataOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;

public class Client {
    public static void main(String[] args) throws Exception {
        //1、创建Socket对象,并同时请求与服务端程序的连接
        Socket socket = new Socket("127.0.0.1",8888);

        //创建一个独立的线程,负责机从socket中接收服务发送过来的消息。
        new ClientReaderThread(socket).start();

        //2、从socket通信管道中得到一个字节输出流,用来发数据给服务端程序。
        OutputStream os = socket.getOutputStream();

        //3、把低级的字节输出流包装成数据输出流
        DataOutputStream dos=new DataOutputStream(os);

        Scanner sc=new Scanner(System.in);
        while (true) {
            System.out.println("请说:");
            String msg = sc.nextLine();
            // 一旦用户输入了exit,就退出客户端程片
            if("exit".equals(msg)){
                System.out.println("欢迎您下您光临!");
                dos.close();
                socket.close();
                break;
            }

            // 4、开始写数据出去了
            dos.writeUTF(msg);
            dos.flush();
        }
    }
}

 Server.java

package com.itheima.d6_tcp3;

import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class Server {
    public static List<Socket> onLineSocket = new ArrayList<>();

    public static void main(String[] args) throws Exception {
        System.out.println("======服务端启动======");

        //1、创建ServerSocket的对象,同时为服务端注册口。
        ServerSocket serverSocket = new ServerSocket(8888);

        while (true) {
            //2、使用serverSocket对象,调用个accept方法,等待客户端的连接请求
            Socket socket = serverSocket.accept();
            onLineSocket.add(socket);

            System.out.print("有人上线了!");
            System.out.println(socket.getRemoteSocketAddress());

            //3、从socket迎信管道中得到一个字节输入流。
            new ServiceReaderThread(socket).start();

        }
    }
}

 ServiceReaderThread.class

package com.itheima.d6_tcp3;

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

public class ServiceReaderThread extends Thread {
    private Socket socket;



    public ServiceReaderThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            InputStream is = socket.getInputStream();
            DataInputStream dis = new DataInputStream(is);
            while (true) {
                try {
                    String msg = dis.readUTF();
                    System.out.println(msg);
                    //把这个消息分发给全部客户端进行接收
                    sendMsgToAll(msg);
                } catch (Exception e) {
                    System.out.println("有人下线了!" + socket.getRemoteSocketAddress());
                    Server.onLineSocket.remove(socket);
                    dis.close();
                    socket.close();
                    break;
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void sendMsgToAll(String msg) throws Exception {
        //发送给全部在线的socket管道接收。
        for (Socket onLineSocket : Server.onLineSocket) {
            OutputStream os = onLineSocket.getOutputStream();
            DataOutputStream dos = new DataOutputStream(os);
            dos.writeUTF(msg);
            dos.flush();
        }
    }
}

ClientReaderThread.class

package com.itheima.d6_tcp3;

import java.io.DataInputStream;
import java.io.InputStream;
import java.net.Socket;

public class ClientReaderThread extends Thread{
    private Socket socket;
    public ClientReaderThread(Socket socket){
        this.socket=socket;
    }

    @Override
    public void run() {
        try {
            InputStream is = socket.getInputStream();
            DataInputStream dis = new DataInputStream(is);
            while (true) {
                try {
                    String msg = dis.readUTF();
                    System.out.println(msg);
                    //把这个消息分发给全部客户端进行接收
                } catch (Exception e) {
                    System.out.println("自己下线了!" + socket.getRemoteSocketAddress());
                    Server.onLineSocket.remove(socket);
                    dis.close();
                    socket.close();
                    break;
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4.6.2 实现一个简易版的BS架构

 注意:服务器必须给浏览器响应HTTP协议规定的数据格式,否则浏览器不识别返回的数据

HTTP协议规定:响应给浏览器的数据格式必须满足如下格式

Server.class

package com.itheima.d7_tcp4;

import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class Server {
    public static List<Socket> onLineSocket = new ArrayList<>();

    public static void main(String[] args) throws Exception {
        System.out.println("======服务端启动======");

        //1、创建ServerSocket的对象,同时为服务端注册口。
        ServerSocket serverSocket = new ServerSocket(8080);

        while (true) {
            //2、使用serverSocket对象,调用个accept方法,等待客户端的连接请求
            Socket socket = serverSocket.accept();
            onLineSocket.add(socket);

            System.out.print("有人上线了!");
            System.out.println(socket.getRemoteSocketAddress());

            //3、从socket迎信管道中得到一个字节输入流。
            new ServiceReaderThread(socket).start();


        }
    }
}

 ServerReaderThread.class

package com.itheima.d7_tcp4;

import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;

public class ServiceReaderThread extends Thread {
    private Socket socket;


    public ServiceReaderThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        //立即响应一个网页内容:“你好"给测览器展示。
        try {
            OutputStream os=socket.getOutputStream();
            PrintStream ps=new PrintStream(os);
            ps.println("HTTP/1.1 200 OK");
            ps.println("Content-Type:text/html;charset=UTF-8");
            ps.println();//****************必须空一行*********************
            ps.println("<div style='color:red;font-size:20px;text-align:center'>你好!</div>");
            ps.close();
            socket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4.6.2.1 拓展知识:每次请求都开一个新线程,到底好不好?

使用线程池进行优化

 Server.class

package com.itheima.d8_tcp5;

import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Server {
    public static List<Socket> onLineSocket = new ArrayList<>();

    public static void main(String[] args) throws Exception {
        System.out.println("======服务端启动======");

        //1、创建ServerSocket的对象,同时为服务端注册口。
        ServerSocket serverSocket = new ServerSocket(8080);

        // 创建出一个线程池负责处理通信管道的任务。
        ThreadPoolExecutor pool = new ThreadPoolExecutor(13 * 2, 13 * 2, 0, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(8), Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());

        while (true) {
            //2、使用serverSocket对象,调用个accept方法,等待客户端的连接请求
            Socket socket = serverSocket.accept();
            onLineSocket.add(socket);

            System.out.print("有人上线了!");
            System.out.println(socket.getRemoteSocketAddress());

            //3、从socket迎信管道中得到一个字节输入流。
           pool.execute(new ServerReaderRunnable(socket));

        }
    }
}

ServerReaderRunnable.class

package com.itheima.d8_tcp5;

import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;

public class ServerReaderRunnable implements Runnable {
    private Socket socket;


    public ServerReaderRunnable(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        //立即响应一个网页内容:“你好"给测览器展示。
        try {
            OutputStream os=socket.getOutputStream();
            PrintStream ps=new PrintStream(os);
            ps.println("HTTP/1.1 200 OK");
            ps.println("Content-Type:text/html;charset=UTF-8");
            ps.println();//****************必须空一行*********************
            ps.println("<div style='color:red;font-size:20px;text-align:center'>你好!</div>");
            ps.close();
            socket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值