精华内容
下载资源
问答
  • 天生支持异步编程的语言如 NodeJS, Golang 等, 创建一个异步 routine 成本非常小, 这确实是一个非常方便功能. 比如用在网络爬虫程序开发, 对于每一个要抓取 URL 就启动一个 routine, 类似启动一个线程, 既能...

    天生支持异步编程的语言如 NodeJS, Golang 等, 创建一个异步 routine 的成本非常小, 这确实是一个非常方便的功能. 比如用在网络爬虫程序的开发, 对于每一个要抓取的 URL 就启动一个 routine, 类似启动一个线程, 既能充分利用 CPU 多核, 代码也很简洁.

    正因为太方便, 所以常常被滥用, 并引发许多严重坑. 下面分析一下.

    1. 拖垮了所依赖的服务

    写异步编程的程序员是爽了, 但维护数据库的 DBA 却要哭了. 异步编程程序员每一个查询可以轻松的异步, 但数据库的处理能力就那么多, 最直接的后果是数据库挂了. 回到网络爬虫的例子, 如果爬虫本身不做控制, 可能就把对方的网站拖垮了.

    2. 用完了 socket 连接数

    一般的异步编程语言的 runtime 会对每个程序只起一个进程, 每一个进程的最大连接数是有限制的, 比如一般的桌面系统是 256, 所以, 虽然异步的成本很小, 但很快就会用完 socket 连接数, 想再增加并发也增加不了了. 而且, 用完了最大连接数, 还经常会触发其它严重的问题.

    3. 用完了本机端口

    这个坑和前一个有些类似. 常见的程序一般只连一台数据库服务器的一个实例, 这样, 程序最多只能连 3 万多个连接, 这时端口就会被用光, 因为操作系统一般从 3 万多开始分配临时端口号, 最大 65535. 如果并发太多导致保持了太多的网络连接, 这时, 你就会看到你的异步编程开发出来的程序报错: Cannot assign requested address. 这时, 整个操作系统都会受不良影响!

    如何解决?

    其实, 要解决这些坑, 必须异步变同步. 什么? 异步变同步?

    其实, 就是通过一个同步队列, 控制一下异步的并发量. 所以, 异步编程是和队列(排队)紧密相连, 如果你的异步编程没有用到队列, 那么你的程序就必然存在隐患! 除非你能确保异步调用不会爆炸性增长. 这是一条真理!

    例如网络爬虫的例子, 为了控制抓取的并发量, 就要通过某种策略, 把要抓取的 URL 放到队列中, 控制在队列中同时存在的同一个域名的 URL 数量, 然后再异步地从这个队列领取 URL 进行抓取, 这就不会把别人的网站拖垮了.

    不过, 具体用哪个策略, 是和业务相关的. 其实这个策略的实现, 开发的工作量不一定小, 有时, 异步不异步根本解决不了太大的问题, 这个策略才是工作量的大头.

    欢迎加入我爱机器学习QQ14群:336582044

    getqrcode.jpg

    微信扫一扫,关注我爱机器学习公众号

    展开全文
  • Java语言的网络编程

    2020-10-11 22:04:19
    网络编程,就是在一定协议下,实现两台计算机通信程序。 1.2网络通信协议 **网络通信协议:**通过计算机网络可以使多台计算机实现连接,位于同一个网络中计算机在进行连接和通信时需要遵守一定规则。 ...

    网络编程入门

    1.1软件结构

    • C/S结构 :全称为Client/Server结构,是指客户端和服务器结构。常见程序有QQ、迅雷等软件。
    • B/S结构 :全称为Browser/Server结构,是指浏览器和服务器结构。常见浏览器有谷歌、火狐等。
    • 网络编程,就是在一定的协议下,实现两台计算机的通信的程序。

    1.2网络通信协议

    • **网络通信协议:**通过计算机网络可以使多台计算机实现连接,位于同一个网络中的计算机在进行连接和通信时需要遵守一定的规则。
    • TCP/IP协议: 传输控制协议/因特网互联协议( Transmission Control Protocol/Internet Protocol),是Internet最基本、最广泛的协议。它定义了计算机如何连入因特网,以及数据如何在它们之间传输的标准。它的内部包含一系列的用于处理数据通信的协议,并采用了4层的分层模型,每一层都呼叫它的下一层所提供的协议来完成自己的需求。
    • TCP/IP协议中的四层分别是应用层、传输层、网络层和链路层,每层分别负责不同的通信功能。
    1. 链路层:链路层是用于定义物理传输通道,通常是对某些网络连接设备的驱动协议,例如针对光纤、网线提供的驱动。
    2. 网络层:网络层是整个TCP/IP协议的核心,它主要用于将传输的数据进行分组,将分组数据发送到目标计算机或者网络。
    3. 运输层:主要使网络程序进行通信,在进行网络通信时,可以采用TCP协议,也可以采用UDP协议。
    4. 应用层:主要负责应用程序的协议,例如HTTP协议、FTP协议等。

    1.3协议分类

    java.net 包中提供了两种常见的网络协议的支持:

    • UDP:用户数据报协议(User Datagram Protocol)。UDP是无连接通信协议,即在数据传输时,数据的发送端和接收端不建立逻辑连接。
      特点:数据被限制在64kb以内,超出这个范围就不能发送了。
      数据报(Datagram):网络传输的基本单位 。
    • TCP:传输控制协议 (Transmission Control Protocol)。TCP协议是面向连接的通信协议,即传输数据之前,在发送端和接收端建立逻辑连接,然后再传输数据,它提供了两台计算机之间可靠无差错的数据传输。

    在TCP连接中必须要明确客户端与服务器端,由客户端向服务端发出连接请求,每次连接的创建都需要经过“三次握手”。

    • 三次握手:TCP协议中,在发送数据的准备阶段,客户端与服务器之间的三次交互,以保证连接的可靠。
      • 第一次握手,客户端向服务器端发出连接请求,等待服务器确认。
      • 第二次握手,服务器端向客户端回送一个响应,通知客户端收到了连接请求。
      • 第三次握手,客户端再次向服务器端发送确认信息,确认连接。

    1.4网络编程三要素

    协议

    • **协议:**计算机网络通信必须遵守的规则,已经介绍过了,不再赘述。

    IP地址

    • IP地址:指互联网协议地址(Internet Protocol Address),俗称IP。IP地址用来给一个网络中的计算机设备做唯一的编号。其相当于“手机号码”。

    • IPv4:是一个32位的二进制数,通常被分为4个字节,表示成a.b.c.d 的形式,例如192.168.65.100 。其中a、b、c、d都是0~255之间的十进制整数,那么最多可以表示42亿个。

    • IPv6:由于互联网的蓬勃发展,IP地址的需求量愈来愈大,但是网络地址资源有限,使得IP的分配越发紧张。
      常用命令

    • 查看本机IP地址,在控制台输入:

    ipconfig
    
    • 检查网络是否连通,在控制台输入:
    ping 空格 IP地址
    ping 220.181.57.216
    

    特殊的IP地址

    • 本机IP地址:127.0.0.1localhost

    端口号

    在这里插入图片描述

    TCP 通信程序

    2.1概述

    在这里插入图片描述

    2.2Socket类

    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
    如果服务器已经启动,那么就可以进行交互了。

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

    2.3ServerSocket类

    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)。

    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    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();
        }
    }
    

    综合案例

    3.1文件上传案例

    在这里插入图片描述

    客户端

    文件上传案例的客户端:读取本地文件,上传到服务器,读取服务器回写的数据

    明确:
    数据源: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)。

    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 {
            //1.创建一个本地字节输入流FileInputStream对象,构造方法中绑定要读取的数据源
            FileInputStream fis = new FileInputStream("c:\\1.jpg");
            //2.创建一个客户端Socket对象,构造方法中绑定服务器的IP地址和端口号
            Socket socket = new Socket("127.0.0.1",8888);
            //3.使用Socket中的方法getOutputStream,获取网络字节输出流OutputStream对象
            OutputStream os = socket.getOutputStream();
            //4.使用本地字节输入流FileInputStream对象中的方法read,读取本地文件
            int len = 0;
            byte[] bytes = new byte[1024];
            while ((len = fis.read(bytes))!=-1){
                //5.使用网络字节输出流OutputStream对象中的方法write,把读取到的文件上传到服务器
                os.write(bytes,0,len);
            }
    
            /*
                解决:上传完文件,给服务器写一个结束标记
                void shutdownOutput() 禁用此套接字的输出流。
                对于 TCP 套接字,任何以前写入的数据都将被发送,并且后跟 TCP 的正常连接终止序列。
             */
            socket.shutdownOutput();
    
            //6.使用Socket中的方法getInputStream,获取网络字节输入流InputStream对象
            InputStream is = socket.getInputStream();
    
            System.out.println("$$$$$$$$$$$$$$$$$$$$$$");
    
            //7.使用网络字节输入流InputStream对象中的方法read读取服务回写的数据
            while ((len = fis.read(bytes))!=-1){
                System.out.println(new String(bytes,0,len));
            }
    
            System.out.println("*****************  while死循环打印不到");
    
            //8.释放资源(FileInputStream,Socket)
            fis.close();
            socket.close();
        }
    }
    

    服务器端

    文件上传案例服务器端:读取客户端上传的文件,保存到服务器的硬盘,给客户端回写"上传成功"
    明确:
    数据源:客户端上传的文件
    目的地:服务器的硬盘 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)。

    import java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    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.判断d:\\upload文件夹是否存在,不存在则创建
            File file = new File("d:upload");
            if (!file.exists()){
                file.mkdirs();
            }
    
            //5.创建一个本地字节输出流FileOutputStream对象,构造方法中绑定要输出的目的地
            FileOutputStream fos = new FileOutputStream(file+"1.jpg");
            //6.使用网络字节输入流InputStream对象中的方法read,读取客户端上传的文件
    
            System.out.println("####################");
    
            int len = 0;
            byte[] bytes = new byte[1024];
            while ((len = is.read(bytes))!=-1){
                //7.使用本地字节输出流FileOutputStream对象中的方法write,把读取到的文件保存到服务器的硬盘上
                fos.write(bytes,0,len);
            }
    
            System.out.println("@@@@@@@@@@@@@@@@@@@@@  while死循环打印不到");
    
            //8.使用Socket对象中的方法getOutputStream,获取到网络字节输出流OutputStream对象
            //9.使用网络字节输出流OutputStream对象中的方法write,给客户端回写"上传成功"
            socket.getOutputStream().write("上传成功".getBytes());
            //10.释放资源(FileOutputStream,Socket,ServerSocket)
            fos.close();
            socket.close();
            server.close();
    
        }
    }
    

    文件上传案例阻塞问题

    在这里插入图片描述

    文件上传案例优化(文件命名&循环接收&多线程提高效率)

    客户端

    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 {
            //1.创建一个本地字节输入流FileInputStream对象,构造方法中绑定要读取的数据源
            FileInputStream fis = new FileInputStream("c:\\1.jpg");
            //2.创建一个客户端Socket对象,构造方法中绑定服务器的IP地址和端口号
            Socket socket = new Socket("127.0.0.1",8888);
            //3.使用Socket中的方法getOutputStream,获取网络字节输出流OutputStream对象
            OutputStream os = socket.getOutputStream();
            //4.使用本地字节输入流FileInputStream对象中的方法read,读取本地文件
            int len = 0;
            byte[] bytes = new byte[1024];
            while((len = fis.read(bytes))!=-1){
                //5.使用网络字节输出流OutputStream对象中的方法write,把读取到的文件上传到服务器
                os.write(bytes,0,len);
            }
    
            /*
                解决:上传完文件,给服务器写一个结束标记
                void shutdownOutput() 禁用此套接字的输出流。
                对于 TCP 套接字,任何以前写入的数据都将被发送,并且后跟 TCP 的正常连接终止序列。
             */
            socket.shutdownOutput();
    
            //6.使用Socket中的方法getInputStream,获取网络字节输入流InputStream对象
            InputStream is = socket.getInputStream();
    
    
    
            //7.使用网络字节输入流InputStream对象中的方法read读取服务回写的数据
            while((len = is.read(bytes))!=-1){
                System.out.println(new String(bytes,0,len));
            }
    
    
            //8.释放资源(FileInputStream,Socket)
            fis.close();
            socket.close();
        }
    }
    

    服务器

    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.Random;
    
    public class TCPServer {
        public static void main(String[] args) throws IOException {
            //1.创建一个服务器ServerSocket对象,和系统要指定的端口号
            ServerSocket server = new ServerSocket(8888);
            //2.使用ServerSocket对象中的方法accept,获取到请求的客户端Socket对象
    
            /*
              让服务器一直处于监听状态(死循环accept方法)
              有一个客户端上传文件,就保存一个文件
            */
            while (true){
                Socket socket = server.accept();
    
                /*
                   使用多线程技术,提高程序的效率
                   有一个客户端上传文件,就开启一个线程,完成文件的上传
                 */
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            //3.使用Socket对象中的方法getInputStream,获取到网络字节输入流InputStream对象
                            InputStream is = socket.getInputStream();
                            //4.判断d:\\upload文件夹是否存在,不存在则创建
                            File file =  new File("d:\\upload");
                            if(!file.exists()){
                                file.mkdirs();
                            }
    
                        /*
                            自定义一个文件的命名规则:防止同名的文件被覆盖
                            规则:域名+毫秒值+随机数
                         */
                            String fileName;
                            fileName = "itcase" + System.currentTimeMillis() + new Random(999999)+"1.jpg";
    
                            //5.创建一个本地字节输出流FileOutputStream对象,构造方法中绑定要输出的目的地
                            //FileOutputStream fos = new FileOutputStream(file+"\\1.jpg");
                            FileOutputStream fos = new FileOutputStream(file+"\\"+fileName);
                            //6.使用网络字节输入流InputStream对象中的方法read,读取客户端上传的文件
    
    
                            int len =0;
                            byte[] bytes = new byte[1024];
                            while((len = is.read(bytes))!=-1){
                                //7.使用本地字节输出流FileOutputStream对象中的方法write,把读取到的文件保存到服务器的硬盘上
                                fos.write(bytes,0,len);
                            }
    
    
                            //8.使用Socket对象中的方法getOutputStream,获取到网络字节输出流OutputStream对象
                            //9.使用网络字节输出流OutputStream对象中的方法write,给客户端回写"上传成功"
                            socket.getOutputStream().write("上传成功".getBytes());
                            //10.释放资源(FileOutputStream,Socket,ServerSocket)
                            fos.close();
                            socket.close();
                        }catch (IOException e){
                            System.out.println(e);
                        }
                    }
                }).start();
            }
            //服务器就不用关闭
            //server.close();
        }
    }
    

    3.2模拟B\S服务器

    分析

    在这里插入图片描述

    BS版本TCP服务器

    import java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class TCPServer {
        public static void main(String[] args) throws IOException {
            //创建一个服务器ServerSocket,和系统要指定的端口号
            ServerSocket server = new ServerSocket(8080);
            //使用accept方法获取到请求的客户端对象
            Socket socket = server.accept();
            //使用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 /day11/web/index.html HTTP/1.1
            String line = br.readLine();
            //把读取的信息机型 切割,只要中间部分/day11/web/index.html
            String[] arr = line.split(" ");
            //把路径前边的/去掉,进行截取day11/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();
            server.close();
        }
    }
    
    import java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    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 /day11/web/index.html HTTP/1.1
                            String line = br.readLine();
                            System.out.println(line);
                            //把读取的信息机型 切割,只要中间部分/day11/web/index.html
                            String[] arr = line.split(" ");
                            //把路径前边的/去掉,进行截取day11/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();
    }
    

    在这里插入图片描述

    展开全文
  • 1. 常见编程语言介绍

    2019-09-14 20:06:38
    (2)C++:混合语言,主要领域有科学计算、操作系统,网络通讯,系统开发、引擎开发,运行效率比Java高。 (3)Java:广泛应用于企业级软件开发、安卓移动开发、大数据云计算等领域,几乎涉及IT所有行业。 (4)...

    (1)C语言:诞生于1972年,可以称之为现代高级语言的鼻祖,由著名的贝尔实验室发明。C语言是人们追求结构化、模块化、高效率的“语言之花”。

    (2)C++:混合语言,主要领域有科学计算、操作系统,网络通讯,系统开发、引擎开发,运行效率比Java高。

    (3)Java:广泛应用于企业级软件开发、安卓移动开发、大数据云计算等领域,几乎涉及IT所有行业。

    (4)PHP:一般用于WEB开发领域,适合于大量的中小型网站以及某些大型网站。

    (5)Object-CSwift语言:IOS开发。

    (6)JavaScript语言:浏览器端的效果开发,使用Node.js来开发服务器,H5开发的核心。

    (7)Python:(胶水语言),很容易把C和C++代码粘和在一起,图像处理、科学计算、web编程、多媒体应用、引擎开发,在机器学习和人工智能上有巨大潜力。

    (8)C#:面向对象的,运行于.NET Framework之上,与java抗衡的高级程序语言,如果开发基于Windows的一些桌面软件,如记事本,QQ影音等,C#是首选。

    (9)Basic:已逐步退出历史舞台。

    (10)COBOL:主要用于大量精确处理数据的商业领域,如金融,银行。

    (11)Pascal:限于大学教育这一块。

    展开全文
  • 海鸟网络验证API,调用示例请移步我上传另一个资源
  • Java语言网络编程

    2020-05-22 20:01:10
    网络通信协议:通信协议是对计算机必须遵守规则,只有遵守这些规则,计算机之间才能进行通信。协议中对数据传输格式、传输速率、传输步骤等做了统一规定,通信双方必须同时遵守,最终完成数据交换。 TCP/IP协议...

    一,网络通信协议

    软件结构
    1,C/S结构 :全称为Client/Server结构,是指客户端和服务器结构。常见程序有QQ、迅雷等软件。
    2,B/S结构 :全称为Browser/Server结构,是指浏览器和服务器结构。常见浏览器有谷歌、火狐等。

    网络通信协议:通信协议是对计算机必须遵守的规则,只有遵守这些规则,计算机之间才能进行通信。协议中对数据的传输格式、传输速率、传输步骤等做了统一规定,通信双方必须同时遵守,最终完成数据交换。
    TCP/IP协议: 传输控制协议/因特网互联协议( Transmission Control Protocol/Internet Protocol),是
    Internet最基本、最广泛的协议。它定义了计算机如何连入因特网,以及数据如何在它们之间传输的标准。

    TCP传输控制协议 (Transmission Control Protocol)。TCP协议是面向连接的通信协议,即传输数据之前,在发送端和接收端建立逻辑连接,然后再传输数据,它提供了两台计算机之间可靠无差错的数据传输。
    三次握手:TCP协议中,在发送数据的准备阶段,客户端与服务器之间的三次交互,以保证连接的可靠。用于例如下载文件、浏览网页等。
    第一次握手,客户端向服务器端发出连接请求,等待服务器确认。
    第二次握手,服务器端向客户端回送一个响应,通知客户端收到了连接请求。
    第三次握手,客户端再次向服务器端发送确认信息,确认连接。

    UDP用户数据报协议(User Datagram Protocol)。UDP协议是一个面向无连接的协议。传输数据时,不需
    要建立连接,不管对方端服务是否启动,直接将数据、数据源和目的地都封装在数据包中,直接发送。每个数据包的大小限制在64k以内。它是不可靠协议,因为无连接,所以传输速度快,但是容易丢失数据。日常应用中,例如视频会议、QQ聊天等。

    二,实现TCP通信程序的java类

    1,客户端: java.net.Socket 类表示。创建 Socket 对象,向服务端发出连接请求,服务端响应请求,两者建立连接开始通信。
    2,服务端: java.net.ServerSocket 类表示。创建ServerSocket 对象,相当于开启一个服务,并等待客户端的连接。

    socket类构造方法
    public Socket(String host, int port) :创建套接字对象并将其连接到指定主机上的指定端口号。如果指定的host是null ,则相当于指定地址为回送地址。
    socket类成员方法
    1,public InputStream getInputStream() : 返回此套接字的输入流。
    2,public OutputStream getOutputStream() : 返回此套接字的输出流。
    3,public void close() :关闭此套接字。

    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 {
            Socket socket = new Socket("127.0.0.1",8888);
    
            OutputStream os = socket.getOutputStream();
            os.write("服务器你好!".getBytes());
    
            InputStream is = socket.getInputStream();
            byte[] bytes = new byte[1024];
            int len = is.read(bytes);
            System.out.println("收到:" + new String(bytes,0,len));
    
            socket.close();
        }
    }
    
    

    ServerSocket类构造方法
    public ServerSocket(int port) :使用该构造方法在创建ServerSocket对象时,就可以将其绑定到一个指定的端口号上,参数port就是端口号。
    ServerSocket类成员方法
    public Socket accept() :侦听并接受连接,返回一个新的Socket对象,用于和客户端实现通信。该方法会一直阻塞直到建立连接。

    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class TCPServer {
        public static void main(String[] args) throws IOException {
            ServerSocket serversocket = new ServerSocket(8888);
            System.out.println("等待客户端连接中...");
            Socket socket = serversocket.accept();
    
            OutputStream os = socket.getOutputStream();
            os.write("你好客户端!".getBytes());
    
            InputStream is = socket.getInputStream();
            byte[] bytes = new byte[1024];
            int len = is.read(bytes);
            System.out.println("收到:" + new String(bytes,0,len));
    
            socket.close();
            serversocket.close();
    
        }
    }
    

    三,文件上传案例

    服务端:

    import java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class FileUploadServer {
        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("E:\\upload");
            if (!file.exists()){
                file.mkdir();
            }
            FileOutputStream fos = new FileOutputStream(file+"\\1.jpg");
    
            System.out.println("3333333");//能打印
    
            int len = 0;
            byte[] bytes = new byte[1024];
            while ((len = is.read(bytes))!=-1){ //若is流未关闭或者读不到流终止序列,则一直处于阻塞状态
                fos.write(bytes,0,len);
            }
    
            System.out.println("4444444444");//不能打印
    
            OutputStream os = socket.getOutputStream();
            os.write("上传成功!".getBytes());
    
            socket.close();
            server.close();
            fos.close();
    
        }
    }
    

    客户端:

    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    
    public class FileUploadClient {
        public static void main(String[] args) throws IOException {
            FileInputStream fis = new FileInputStream("d:\\1.jpg");
    
            Socket socket = new Socket("127.0.0.1",8888);
            OutputStream os = socket.getOutputStream();
    
            int len = 0;
            byte[] bytes = new byte[1024];
            while ((len = fis.read(bytes))!=-1){
                os.write(bytes,0,len);//最后没有写入-1
            }
    
            socket.shutdownOutput();//阻塞的解决方法,加入TCP流终止序列
            System.out.println("111111");//能打印
    
            InputStream is = socket.getInputStream();
            while ((len = is.read(bytes))!=-1){
                System.out.println(new String(bytes,0,len));
            }
    
            System.out.println("222222");//不能打印
    
            socket.close();
            fis.close();
        }
    }
    
    

    注意:
    1,read()会读取对端发送过来的数据,如果无数据可读,就会阻塞直到有数据可读,或者到达流的末尾,这个时候返回-1。
    2,在读取文件的时候,文件结尾就是流的结尾;但对于Socket而言不是的,Socket流还在,还是能够继续读写的。

    解决socket网络流中read()方法阻塞问题:上传完文件,给服务器写一个结束标记或对端关闭网络socket流(此时将不能发送结束数据)。
    结束标记:void shutdownOutput(),禁用此套接字的输出流。对于TCP套接字,任何以前写入的数据都将被发送,并且后跟TCP的正常连接终止序列。

    服务器升级版(一直开启状态+修改上传文件名+多线程上传):

    import java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.Random;
    
    public class FileUploadServer {
        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("E:\\upload");
                            if (!file.exists()){
                                file.mkdir();
                            }
                            String filename = "image" + System.currentTimeMillis() + new Random().nextInt(99999) + ".jpg";
                            FileOutputStream fos = new FileOutputStream(file+"\\"+filename);
    
    
                            int len = 0;
                            byte[] bytes = new byte[1024];
                            while ((len = is.read(bytes))!=-1){ //若is流未关闭或者读不到流终止序列,则一直处于阻塞状态
                                fos.write(bytes,0,len);
                            }
    
                            OutputStream os = socket.getOutputStream();
                            os.write("上传成功!".getBytes());
    
                            socket.close();
                            fos.close();
                        }catch (Exception e){
                            System.out.println(e);
                        }
                    }
                }).start();
            }
        }
    }
    
    展开全文
  • 这里说的设计创造一门语言,我猜是想创建一门解释性语言,下面我来列举四种常见的解释性语言,看看它们是怎么被实现的。Python。当下最流行的语言,Python的底层主要是由C、C++(后期可能加入了部分Java)实现的,...
  • 网络编程

    2021-01-26 15:54:58
    Java是 Internet 上的语言,它从语言级上提供了对网络应用程序的支持,程序员能够很容易开发常见的网络应用程序。 Java提供的网络类库,可以实现无痛的网络连接,联网的底层细节被隐藏在 Java 的本机安装系统里,由 ...
  • Java中的网络编程

    2019-05-30 09:54:35
    网络编程的概述:1:Java是Internet上的语言,它从语言上提供了对网络应用程序的支持,程序员能够很容易开发常见的网络应用程序。2.Java提供的网络内库,可以实现互通的网络连接,网络的底层细节被隐藏在Java的本机...
  • 编程语言预科

    2020-06-19 22:49:59
    编程语言预科-01 什么是计算机 Computer:全称电子计算机,俗称电脑。 能够按照程序运行,自动、高速处理海量数据的现代化智能电子设备。 由硬件和软件所组成 常见的形式有台式计算机、笔记本计算机、大型计算机等...
  • 11-Java的网络编程

    2020-11-09 21:42:39
    Java是 Internet 上的语言,它从语言级上提供了对网络应用程序的支持,程序员能够很容易开发常见的网络应用程序。 Java提供的网络类库,可以实现无痛的网络连接,联网的底层细节被隐藏在 Java 的本机安装系统里,...
  • JAVA网络编程

    2019-10-09 07:44:32
    网络编程 ...java是Internet上的语言,它从语言寄级上提供了对网络应用程序的支持,程序员能够很容易的开发常见的网络应用程序 java提供网络类库,可以实现无痛的网络连接,联网的底层细节被隐...
  • Java网络编程

    2020-11-28 17:29:17
    Java网络编程 1、网络编程 1.1、概述 ...2、Java是 Internet 上的语言,它从语言级上提供了对网络应用程 序的支持,程序员能够很容易开发常见的网络应用程序。 3、Java提供的网络类库,可以实现无痛的网络连
  • 网络编程概述

    2018-07-23 23:43:03
    Java是Internet上的语言,它从语言级上提供了对网络应用程序的支持,程序员能够很容易开发常见的网络应用程序 Java提供的网络类库,可以实现无痛的网络连接,联网的底层细节被隐藏在Java的本机安装系统里,由jvm...
  • Java 网络编程

    2020-12-24 20:27:01
    Java是 Internet上的语言,它从语言级上提供了对网络应用程序的支持,程序员能够很容易开发常见的网络应用程序。 Java提供的网络类库,可以实现无痛的网络连接,联网的底层细节被隐藏在Java的本机安装系统里,由JVM...
  • Java是Internet上的语言,它从语言级上提供了对网络应用程序的支持,程序员能够很容易开发常见的网络应用程序。 Java提供网络类库,可以实现无痛的网络连接,联网的底层细节被隐藏在Java的本机安装系统中里,由JVM...
  • 1.Java是 Internet 上的语言,它从语言级上提供了对网络应用程序的支持,程序员能够很容易开发常见的网络应用程序。 2.Java提供的网络类库,可以实现无痛的网络连接,联网的底层细节被隐藏在 Java 的本机安装系统里...
  • 目前,许多名牌学校大学生应聘搓澡工、捏脚工或酒店服务员、四川某企业500元月薪试用本科生等新闻常见诸报端;这些新闻背后,传递着这样一个信息:随着高校逐年扩招,昔日“天之骄子”,今朝就业形势不容乐观...
  • 003_多种编程语言介绍

    2019-04-12 10:44:53
    目录常见编程语言介绍C语言C++JAVAPHPObject-C和Swift语言JavaScript语言Python 常见编程语言介绍 C语言 现代高级语言鼻祖 老鸟建议 经典 学习很有必要 线代社会流行程度仍然排名前三 C++ ...
  • 进入21世纪,机器人已经成为现代工业不可缺少工具,它标志着工业现代化程度。近年来,随着计算机技术,微电子技术及网络技术快速发展,机器人技术...目前,不像数控机床那样有APT语言,机器人编程还没有公认...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 834
精华内容 333
关键字:

常见的网络编程语言