前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >网络编程

网络编程

作者头像
全栈程序员站长
发布2021-05-20 09:37:24
4450
发布2021-05-20 09:37:24
举报

软件结构 C/S 和 B/S 网络通信协议 协议就是个规则 网络通信协议的分类 UDP TCP/IP 端口号

在这里插入图片描述
在这里插入图片描述

TCP通信

在这里插入图片描述
在这里插入图片描述

TCP通信的客户端代码实现

代码语言:javascript
复制
package com.itheima.demo01.TCP;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

/* TCP通信的客户端:向服务器发送连接请求,给服务器发送数据,读取服务器回写的数据 表示客户端的类: java.net.Socket:此类实现客户端套接字(也可以就叫“套接字”)。套接字是两台机器间通信的端点。 套接字:包含了IP地址和端口号的网络单位 构造方法: Socket(String host, int port) 创建一个流套接字并将其连接到指定主机上的指定端口号。 参数: String host:服务器主机的名称/服务器的IP地址 int port:服务器的端口号 成员方法: OutputStream getOutputStream() 返回此套接字的输出流。 InputStream getInputStream() 返回此套接字的输入流。 void close() 关闭此套接字。 实现步骤: 1.创建一个客户端对象Socket,构造方法绑定服务器的IP地址和端口号 2.使用Socket对象中的方法getOutputStream()获取网络字节输出流OutputStream对象 3.使用网络字节输出流OutputStream对象中的方法write,给服务器发送数据 4.使用Socket对象中的方法getInputStream()获取网络字节输入流InputStream对象 5.使用网络字节输入流InputStream对象中的方法read,读取服务器回写的数据 6.释放资源(Socket) 注意: 1.客户端和服务器端进行交互,必须使用Socket中提供的网络流,不能使用自己创建的流对象 2.当我们创建客户端对象Socket的时候,就会去请求服务器和服务器经过3次握手建立连接通路 这时如果服务器没有启动,那么就会抛出异常ConnectException: Connection refused: connect 如果服务器已经启动,那么就可以进行交互了 */
public class TCPClient {
   
    public static void main(String[] args) throws IOException {
   
        //1.创建一个客户端对象Socket,构造方法绑定服务器的IP地址和端口号
        Socket socket = new Socket("127.0.0.1",8888);
        //2.使用Socket对象中的方法getOutputStream()获取网络字节输出流OutputStream对象
        OutputStream os = socket.getOutputStream();
        //3.使用网络字节输出流OutputStream对象中的方法write,给服务器发送数据
        os.write("你好服务器".getBytes());

        //4.使用Socket对象中的方法getInputStream()获取网络字节输入流InputStream对象
        InputStream is = socket.getInputStream();

        //5.使用网络字节输入流InputStream对象中的方法read,读取服务器回写的数据
        byte[] bytes = new byte[1024];
        int len = is.read(bytes);
        System.out.println(new String(bytes,0,len));

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

    }

}

TCP通信的服务器端代码实现

代码语言:javascript
复制
package com.itheima.demo01.TCP;

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

/* TCP通信的服务器端:接收客户端的请求,读取客户端发送的数据,给客户端回写数据 表示服务器的类: java.net.ServerSocket:此类实现服务器套接字。 构造方法: ServerSocket(int port) 创建绑定到特定端口的服务器套接字。 服务器端必须明确一件事情,必须的知道是哪个客户端请求的服务器 所以可以使用accept方法获取到请求的客户端对象Socket 成员方法: Socket accept() 侦听并接受到此套接字的连接。 服务器的实现步骤: 1.创建服务器ServerSocket对象和系统要指定的端口号 2.使用ServerSocket对象中的方法accept,获取到请求的客户端对象Socket 3.使用Socket对象中的方法getInputStream()获取网络字节输入流InputStream对象 4.使用网络字节输入流InputStream对象中的方法read,读取客户端发送的数据 5.使用Socket对象中的方法getOutputStream()获取网络字节输出流OutputStream对象 6.使用网络字节输出流OutputStream对象中的方法write,给客户端回写数据 7.释放资源(Socket,ServerSocket) */
public class TCPServer {
   
    public static void main(String[] args) throws IOException {
   
        //1.创建服务器ServerSocket对象和系统要指定的端口号
        ServerSocket server = new ServerSocket(8888);
        //2.使用ServerSocket对象中的方法accept,获取到请求的客户端对象Socket
        Socket socket = server.accept();
        //3.使用Socket对象中的方法getInputStream()获取网络字节输入流InputStream对象
        InputStream is = socket.getInputStream();
        //4.使用网络字节输入流InputStream对象中的方法read,读取客户端发送的数据
        byte[] bytes = new byte[1024];
        int len = is.read(bytes);
        System.out.println(new String(bytes,0,len));
        //5.使用Socket对象中的方法getOutputStream()获取网络字节输出流OutputStream对象
        OutputStream os = socket.getOutputStream();
        //6.使用网络字节输出流OutputStream对象中的方法write,给客户端回写数据
        os.write("收到谢谢".getBytes());
        //7.释放资源(Socket,ServerSocket)
        socket.close();
        server.close();
    }
}

综合案例_文件上传的原理

在这里插入图片描述
在这里插入图片描述

文件上传案例的客户端和服务器端

代码语言:javascript
复制
/* 文件上传案例的客户端:读取本地文件,上传到服务器,读取服务器回写的数据 明确: 数据源:c:\\1.jpg 目的地:服务器 实现步骤: 1.创建一个本地字节输入流FileInputStream对象,构造方法中绑定要读取的数据源 2.创建一个客户端Socket对象,构造方法中绑定服务器的IP地址和端口号 3.使用Socket中的方法getOutputStream,获取网络字节输出流OutputStream对象 4.使用本地字节输入流FileInputStream对象中的方法read,读取本地文件 5.使用网络字节输出流OutputStream对象中的方法write,把读取到的文件上传到服务器 6.使用Socket中的方法getInputStream,获取网络字节输入流InputStream对象 7.使用网络字节输入流InputStream对象中的方法read读取服务回写的数据 8.释放资源(FileInputStream,Socket) */
 
 package com.itheima.demo02.FileUpload;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class TCPClient {
   
    public static void main(String[] args) throws IOException {
   
        FileInputStream fis = new FileInputStream("11_Net\\1.jpg");
        Socket socket = new Socket("192.168.1.106",8888);
        OutputStream outputStream = socket.getOutputStream();

        int len = 0;
        byte[] bytes = new byte[1024];
        while((len = fis.read(bytes))!=-1){
   
            outputStream.write(bytes,0,len);
        }

        InputStream inputStream = socket.getInputStream();
        while((len = inputStream.read())!=-1){
   
            System.out.println(new String(bytes,0,len));
        }

        fis.close();
        socket.close();

    }
}
代码语言:javascript
复制
/* 文件上传案例服务器端:读取客户端上传的文件,保存到服务器的硬盘,给客户端回写"上传成功" 明确: 数据源:客户端上传的文件 目的地:服务器的硬盘 d:\\upload\\1.jpg 实现步骤: 1.创建一个服务器ServerSocket对象,和系统要指定的端口号 2.使用ServerSocket对象中的方法accept,获取到请求的客户端Socket对象 3.使用Socket对象中的方法getInputStream,获取到网络字节输入流InputStream对象 4.判断d:\\upload文件夹是否存在,不存在则创建 5.创建一个本地字节输出流FileOutputStream对象,构造方法中绑定要输出的目的地 6.使用网络字节输入流InputStream对象中的方法read,读取客户端上传的文件 7.使用本地字节输出流FileOutputStream对象中的方法write,把读取到的文件保存到服务器的硬盘上 8.使用Socket对象中的方法getOutputStream,获取到网络字节输出流OutputStream对象 9.使用网络字节输出流OutputStream对象中的方法write,给客户端回写"上传成功" 10.释放资源(FileOutputStream,Socket,ServerSocket) */
package com.itheima.demo02.FileUpload;

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

public class TCPServer {
   
    public static void main(String[] args) throws IOException {
   
        ServerSocket server = new ServerSocket(8888);
        Socket socket = server.accept();
        InputStream is = socket.getInputStream();
        File file = new File("d:\\upload");
        if(!file.exists()){
   
            file.mkdir();
        }
        FileOutputStream fos = new FileOutputStream(file+"\\1.jpg");

        int len = 0;
        byte[] bytes = new byte[1024];
        while((len = is.read(bytes))!=-1){
   
            fos.write(bytes,0,len);
        }

        OutputStream os = socket.getOutputStream();
        os.write("上传成功".getBytes());

        fos.close();
        socket.close();
        server.close();
    }
}

综合案例_文件上传案例阻塞问题

在这里插入图片描述
在这里插入图片描述

客户端改下

代码语言:javascript
复制
package com.itheima.demo02.FileUpload;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class TCPClient {
   
    public static void main(String[] args) throws IOException {
   
        FileInputStream fis = new FileInputStream("11_Net\\1.jpg");
        Socket socket = new Socket("192.168.1.106",8888);
        OutputStream outputStream = socket.getOutputStream();

        int len = 0;
        byte[] bytes = new byte[1024];
        while((len = fis.read(bytes))!=-1){
   
            outputStream.write(bytes,0,len);
        }
        socket.shutdownOutput();

        InputStream inputStream = socket.getInputStream();
        while((len = inputStream.read(bytes))!=-1){
   
            System.out.println(new String(bytes,0,len));
        }

        fis.close();
        socket.close();

    }
}

综合案例_文件上传案例优化(文件命名&循环接收&多线程提高效率) 服务器端的改进

代码语言:javascript
复制
package com.itheima.demo03.FileUpload;

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

public class TCPServer {
   
    public static void main(String[] args) throws IOException {
   
        ServerSocket server = new ServerSocket(8888);
        while (true) {
   
            Socket socket = server.accept();

            new Thread(new Runnable() {
   
                @Override
                public void run() {
   
                    try{
   
                        InputStream is = socket.getInputStream();
                        File file = new File("d:\\upload");
                        if (!file.exists()) {
   
                            file.mkdir();
                        }

                        String fileName ="itcast"+System.currentTimeMillis()+new Random().nextInt(999999)+".jpg";
                        FileOutputStream fos = new FileOutputStream(file + "\\"+fileName);

                        int len = 0;
                        byte[] bytes = new byte[1024];
                        while ((len = is.read(bytes)) != -1) {
   
                            fos.write(bytes, 0, len);
                        }

                        OutputStream os = socket.getOutputStream();
                        os.write("上传成功".getBytes());

                        fos.close();
                        socket.close();

                    }catch (IOException e){
   
                        System.out.println(e);
                    }
                }
            }).start();
            //server.close();
        }
    }
}

模拟BS服务器分析

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
package com.itheima.demo04.BSTCP;

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

/* 创建BS版本TCP服务器 */
public class TCPServerThread {
   
    public static void main(String[] args) throws IOException {
   
        //创建一个服务器ServerSocket,和系统要指定的端口号
        ServerSocket server = new ServerSocket(8080);

        /* 浏览器解析服务器回写的html页面,页面中如果有图片,那么浏览器就会单独的开启一个线程,读取服务器的图片 我们就的让服务器一直处于监听状态,客户端请求一次,服务器就回写一次 */
        while(true){
   
            //使用accept方法获取到请求的客户端对象(浏览器)
            Socket socket = server.accept();

            new Thread(new Runnable() {
   
                @Override
                public void run() {
   
                    try {
   
                        //使用Socket对象中的方法getInputStream,获取到网络字节输入流InputStream对象
                        InputStream is = socket.getInputStream();
                        //使用网络字节输入流InputStream对象中的方法read读取客户端的请求信息
                        /*byte[] bytes = new byte[1024]; int len = 0; while((len = is.read(bytes))!=-1){ System.out.println(new String(bytes,0,len)); }*/

                        //把is网络字节输入流对象,转换为字符缓冲输入流
                        BufferedReader br = new BufferedReader(new InputStreamReader(is));
                        //把客户端请求信息的第一行读取出来 GET /11_Net/web/index.html HTTP/1.1
                        String line = br.readLine();
                        System.out.println(line);
                        //把读取的信息进行切割,只要中间部分 /11_Net/web/index.html
                        String[] arr = line.split(" ");
                        //把路径前边的/去掉,进行截取 11_Net/web/index.html
                        String htmlpath = arr[1].substring(1);

                        //创建一个本地字节输入流,构造方法中绑定要读取的html路径
                        FileInputStream fis = new FileInputStream(htmlpath);
                        //使用Socket中的方法getOutputStream获取网络字节输出流OutputStream对象
                        OutputStream os = socket.getOutputStream();

                        // 写入HTTP协议响应头,固定写法
                        os.write("HTTP/1.1 200 OK\r\n".getBytes());
                        os.write("Content-Type:text/html\r\n".getBytes());
                        // 必须要写入空行,否则浏览器不解析
                        os.write("\r\n".getBytes());

                        //一读一写复制文件,把服务读取的html文件回写到客户端
                        int len = 0;
                        byte[] bytes = new byte[1024];
                        while((len = fis.read(bytes))!=-1){
   
                            os.write(bytes,0,len);
                        }

                        //释放资源
                        fis.close();
                        socket.close();
                    }catch (IOException e){
   
                        e.printStackTrace();
                    }
                }
            }).start();


        }


        //server.close();
    }
}

浏览器充当客户端,输入网址:http://192.168.1.106:8080/11_Net/web/index.html

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/100188.html原文链接:

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档