javaweb基础入门——Socket

1.1 了解javaweb

javaweb是写网站的, 网站开发是趋势

javaweb是spring必经之路

1.2 计算机网络基础

用网线和路由,光猫把不同计算机连起来,组成计算机网络系统

电脑有自己的ip地址,同一个网络中通过对方ip来ping他

电脑上的程序通过网络访问其他计算机,程序有自己的端口号

端口:0~65535

ip分为ipv4:四组数字,32bit,ipv6:128bit,现在正在向ipv6过渡

传输层协议:TCP,UDP

TCP:三次握手,四次挥手,保证两台计算机通信可靠

UDP:直接发送,不可靠,简单高效

1.3 Socket 技术

套接字,计算机通信的一种方式,操作系统底层一项通信技术,支持TCP和UDP,Java对Socket完美封装,非常好实现

实现:

服务端

public static void main(String[] args) throws Exception{
    ServerSocket server = new ServerSocket(8080);// 服务端端口 8080
    System.out.println("正在等待客户端->服务端");
        Socket socket = server.accept();//没有客户端连接,线程阻塞,直到有客户端连接为止
        System.out.println("客户端连接,IP地址为: "+socket.getInetAddress().getHostAddress());
}

客户端

public static void main(String[] args) throws Exception{
        Socket socket = new Socket("localhost", 8080);
        System.out.println("已连接到服务端");
    }

先启动服务端,在启动客户端

image-20220515201729854

让服务端循环接受IP地址

public static void main(String[] args) throws Exception{
    ServerSocket server = new ServerSocket(8080);// 服务端端口 8080
    System.out.println("正在等待客户端->服务端");
    while (true){
        Socket socket = server.accept();//没有客户端连接,线程阻塞,直到有客户端连接为止
        System.out.println("客户端连接,IP地址为: "+socket.getInetAddress().getHostAddress());
    }
}

image-20220515211403170

实现多次连接服务端

1.4 用Socket传输数据

用IO流传输网络数据

客户端

public static void main(String[] args) throws Exception{
        Socket socket = new Socket("localhost", 8081);
        Scanner scanner = new Scanner(System.in);
        System.out.println("已连接到服务器");
        OutputStream stream = socket.getOutputStream();
        OutputStreamWriter writer = new OutputStreamWriter(stream);//转换流快速写入内容
        System.out.println("请输入要发送到服务端的内容:");
        String text = scanner.nextLine();
        writer.write(text + '\n');//对方是readline()加换行符
        writer.flush();
        System.out.println("数据已发送" + text);
    }

服务端

public static void main(String[] args) throws Exception{
        ServerSocket server = new ServerSocket(8081);
        System.out.println("等待客户端连接……");
        Socket socket = server.accept();
        System.out.println("客户端已连接,IP地址为:" + socket.getInetAddress().getHostAddress());
        BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        System.out.println("接收到客户端数据:");
        System.out.println(reader.readLine());
        socket.close();
    }

输出

image-20220515212544179

image-20220515212552630

同理服务端也可以接收客户端消息

客户端

public static void main(String[] args) throws Exception{
        try (Socket socket = new Socket("localhost", 8080);
             Scanner scanner = new Scanner(System.in)){
            System.out.println("已连接到服务端!");
            OutputStream stream = socket.getOutputStream();
            OutputStreamWriter writer = new OutputStreamWriter(stream);  //通过转换流来帮助我们快速写入内容
            System.out.println("请输入要发送给服务端的内容:");
            String text = scanner.nextLine();
            writer.write(text+'\n');   //因为对方是readLine()这里加个换行符
            writer.flush();
            System.out.println("数据已发送:"+text);

            BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            System.out.println("收到服务器返回:"+reader.readLine());
        }catch (IOException e){
            System.out.println("服务端连接失败!");
            e.printStackTrace();
        }finally {
            System.out.println("客户端断开连接!");
        }
    }

服务端

public static void main(String[] args) throws Exception{
    try(ServerSocket server = new ServerSocket(8080)){    //将服务端创建在端口8080上
        System.out.println("正在等待客户端连接...");
        Socket socket = server.accept();
        System.out.println("客户端已连接,IP地址为:"+socket.getInetAddress().getHostAddress());
        BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));  //通过
        System.out.print("接收到客户端数据:");
        System.out.println(reader.readLine());
        OutputStreamWriter writer = new OutputStreamWriter(socket.getOutputStream());
        writer.write("已收到!");
        writer.flush();
        socket.close();
    }catch (IOException e){
        e.printStackTrace();
    }
}

image-20220515221021956

image-20220515221030064

手动关闭单向的流

socket.shutdownOutput(); //关闭输出方向的流
socket.shutdownInput();  //关闭输入方向的流

image-20220515232703211

服务器不可能一直等客户端,可以设置一个时间

scoket.setSoTimeout(3000);

image-20220515232941922

手动连接服务端,在我们想要的时候再连接

try(Socket socket = new Socket();
   Scanner scanner = new Scanner(System.in){
       socket.connect(new InetSocketAddress("localhost",8080),1000)
	//手动调用connect方法进行连接

image-20220515234045338

双方由于某种原因连接不到,一方始终持有连接,占用资源,这是我们不想看到的,用setKeepAlive方法解决

socket.setKeepAlive(true);

image-20220515234603130

TCP传输过程中会有一个缓冲区用于数据发送和接收,调节缓冲区大小优化效率

socket.setReceiveBufferSize(25565); //TCP接收缓冲区
socket.setSendBufferSize(25565);	//TCP发送缓冲区

1.5 用Socket传输文件

Socket提供IO流,轻松实现文件传输

客户端

public static void main(String[] args) throws Exception{
        try (Socket socket = new Socket("localhost",8080);){
            FileInputStream fileInputStream = new FileInputStream("a.txt");
            OutputStream stream = socket.getOutputStream();
            byte[] bytes = new byte[1024];
            int i;
            while ((i = fileInputStream.read(bytes)) != -1){
                stream.write(bytes,0,i);
            }
            fileInputStream.close();
            stream.flush();
        }catch (IOException e){
            System.out.println("服务端连接失败!");
            e.printStackTrace();
        }
    }

服务端

public static void main(String[] args) throws Exception{
        try(ServerSocket server = new ServerSocket(8080)){    //将服务端创建在端口8080上
            Socket socket = server.accept();
            InputStream stream = socket.getInputStream();
            FileOutputStream fileOutputStream = new FileOutputStream("net/data.txt");
            byte[] bytes = new byte[1024];
            int i;
            while ((i = stream.read(bytes)) != -1){
                fileOutputStream.write(bytes,0,i);
            }
            fileOutputStream.flush();
            fileOutputStream.close();
        }catch (IOException e){
            e.printStackTrace();
        }
    }

image-20220516001412976

1.6 用浏览器访问Socket服务器

服务端

public static void main(String[] args) throws Exception{
        try(ServerSocket server = new ServerSocket(8080)){    //将服务端创建在端口8080上
            System.out.println("正在等待客户端连接……");
            Socket socket = server.accept();
            System.out.println("客户端已连接,IP地址为:" + socket.getInetAddress().getHostAddress());
            InputStream in = socket.getInputStream();
            System.out.println("接收到客户端数据:");
            while (true){
                int i = in.read();
                if (i == -1)break;
                System.out.print((char) i);
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }

浏览器端

image-20220516101220030

响应

image-20220516101303217

自定义响应内容

try(ServerSocket server = new ServerSocket(8080)){    //将服务端创建在端口8080上
    System.out.println("正在等待客户端连接...");
    Socket socket = server.accept();
    System.out.println("客户端已连接,IP地址为:"+socket.getInetAddress().getHostAddress());
    BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));  //通过
    System.out.println("接收到客户端数据:");
    while (reader.ready()) System.out.println(reader.readLine());   //ready是判断当前流中是否还有可读内容
    OutputStreamWriter writer = new OutputStreamWriter(socket.getOutputStream());
    writer.write("HTTP/1.1 200 Accepted\r\n");   //200是响应码,Http协议规定200为接受请求,400为错误的请求,404为找不到此资源(不止这些,还有很多)
    writer.write("\r\n");   //在请求头写完之后还要进行一次换行,然后写入我们的响应实体(会在浏览器上展示的内容)
    writer.write("lbwnb!");
    writer.flush();
}catch (IOException e){
    e.printStackTrace();
}

打开浏览器访问8080,不能显示,关防火墙也不行,知道原理就行了吧

posted @ 2022-05-16 10:59  鱼子酱caviar  阅读(348)  评论(0)    收藏  举报