网络编程基础篇面试锦囊(面试必备,值得收藏)

 1.网络编程三要素

1.网络通信协议:

  • TCP:传输控制协议 。TCP协议是面向连接的通信协议,即传输数据之前,在发送端和接收端建立逻辑连接,然后再传输数据,它提供了两台计算机之间可靠无差错的数据传输。
  • TCP协议特点: 面向连接,传输数据安全,传输速度低 
    • 连接三次握手:TCP协议中,在发送数据的准备阶段,客户端与服务器之间的三次交互,以保证连接的可靠。
      • 第一次握手,客户端向服务器端发出连接请求,等待服务器确认。
      • 第二次握手,服务器端向客户端回送一个响应,通知客户端收到了连接请求。
      • 第三次握手,客户端再次向服务器端发送确认信息,确认连接。
  • UDP:用户数据报协议。UDP协议是一个面向无连接的协议。传输数据时,不需要建立连接,不管对方端服务是否启动,直接将数据、数据源和目的地都封装在数据包中,直接发送每个数据包的大小限制在64k以内。它是不可靠协议,因为无连接,所以传输速度快,但是容易丢失数据。日常应用中,例如视频会议、QQ聊天等。
  • UDP特点: 面向无连接,传输数据不安全,传输速度快

TCP与UDP区别?

1、 TCP面向连接 (如打电话要先拨号建立连接); UDP是无连接 的,即发送数据之前不需要建立连接

2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付

3、UDP具有较好的实时性,工作效率比TCP高,适用于对高速传输和实时性有较高的通信或广播通信。

4.每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信

5、TCP对系统资源要求较多UDP对系统资源要求较少。

2.IP地址

  • IP地址:指互联网协议地址,俗称IP。IP地址用来给一个网络中的计算机设备做唯一的编号。假如我们把“个人电脑”比作“一台电话”的话,那么“IP地址”就相当于“电话号码”。

常用命令

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

ipconfig

  • 检查网络是否连通,在控制台输入:

 

ping 空格 IP地址

ping 220.181.57.216

ping www.baidu.com

 特殊的IP地址

 

  • 本机IP地址:127.0.0.1、localhost 。

3.端口号

网络的通信,本质上是两个进程(应用程序)的通信。每台计算机都有很多的进程,那么在网络通信时,如何区分这些进程呢?

如果说IP地址可以唯一标识网络中的设备,那么端口号就可以唯一标识设备中的进程(应用程序)了。

  • 端口号:用两个字节表示的整数,它的取值范围是0-65535。其中,0-1023之间的端口号用于一些知名的网络服务和应用,普通的应用程序需要使用1024以上的端口号。如果端口号被另外一个服务或应用所占用,会导致当前程序启动失败。

利用协议+IP地址+端口号 三元组合,就可以标识网络中的进程了,那么进程间的通信就可以利用这个标识与其它进程进行交互。

2.说一下什么是Http协议?

客户端和 服务器端之间数据传输的格式规范,格式简称为“超文本传输协议”。是一个基于请求与响应模式的.无状态的.应用层的协议,基于TCP的连接方式。

3.http和Https主要区别

1.https协议需要到ca申请证书,一般免费的证书比较少,因而需要一定的费用。

2.http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议

3.http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443

4.http的连接很简单,是无状态的;https协议是由SSL+Http协议构建的可加密传输、身份认证的网络协议,比http协议安全。

4.get与post请求区别?

区别1:

get重点在从服务器上获取资源,post重点在向服务器发送数据;

区别2:

get传输数据是通过URL请求,以field(字段)= value的形式,置于URL后,并用"?"连接,多个请求数据间用"&"连接,如http://127.0.0.1/Test/LogIn.action?name=admin&password=admin,这个过程用户是可见的;

post传输数据通过Http的post机制,将字段与对应值封存在请求实体中发送给服务器,这个过程对用户是不可见的;

区别3:

Get传输的数据量小,因为受URL长度限制,但效率较高

Post可以传输大量数据,所以上传文件时只能用Post方式;

区别4:

Get是不安全的,因为URL是可见的,可能会泄露私密信息,如密码等;

Post较get安全性较高;

区别5:

get方式只能支持ASCII字符,向服务器传的中文字符可能会乱码。

post支持标准字符集,可以正确传递中文字符。

5. http中重定向和请求转发的区别?

15189e718c1e48658c0e0a6ad6794525.png

本质区别:,请求转发是服务器端行为,重定向是客户端行为。

请求转发特点:1.一次请求

 2.浏览器地址不变

 3.可以跳转到WEB-INF中的资源,但是不能跳转到其他的项目资源(本项目)

重定向特点:1.两次请求

 2.地址栏路径改变,

 3.重定向的路径写绝对路径(带域名/ip地址的,如果是同一个项目里面的域名/ip地址可以省略)

 4.重定向不能重定向到WEB-INF下的资源

 5.重定向的路径可以是项目内部的,也可以是项目以外的(eg:百度)

6.Cookie 和 Session

cookie是客户端(浏览器)端的技术用户浏览的信息以键值对(key=value)的形式保存在浏览器上。如果没有关闭浏览器,再次访问服务器,会把cookie带到服务端,服务端就可以做响应的处理。

session是服务器端的技术。服务器为每一个浏览器开辟一块内存空间,即session对象。由于session对象是每一个浏览器特有的,所以用户的记录可以存放在session对象中。同时,每一个session对象都对应一个sessionId,服务器把sessionId写到cookie中,再次访问的时候,浏览器把sessionId带过来,找到对应的session对象

Cookie 和 session 的不同点:

  • cookie是保存在浏览器端的,大小和个数都有限制session是保存在服务器端的, 原则上大小是没有限制(实际开发里面也不会存很大大小), 安全一些。
  • cookie不支持中文,并且只能存储字符串session可以存储基本数据类型,集合,对象等

沉浸式体验网络编程:


7.InetAddress类

  • 一个该类的对象就代表一个IP地址对象。

InetAddress类的方法

  • static InetAddress getLocalHost()   获得本地主机IP地址对象
  • static InetAddress getByName(String host) 根据IP地址字符串或主机名获得对应的IP地址对象
  • String getHostName();获得主机名
  • String getHostAddress();获得IP地址字符串

8.UDP通信

UDP是面向无连接的、不需要确认双方是否存在,所以它是不可靠的协议。

Java提供了一个类叫DatagramSocket来完成基于UDP协议的收发数据。

使用DatagramSocket收发数据时,数据要以数据包的形式体现,一个数据包限制在64KB以内

现在左边的人要扔一盘韭菜到右边,这里的韭菜就是数据,但是数据需要用一个盘子装起来,这里的盘子就是DatagramPacket数据包的意思。通信双方都需要有DatagramSocket(扔、接韭菜人),还需要有DatagramPacket(装韭菜的盘子)

9953171ed9ed4455afb3ca543e8113d4.png

需求:客户端程序发一个字符串数据给服务端,服务端程序接收数据并打印。

e4fbb086ffc9412280e5efea3db78439.png1.客户端程序

/**
 * 目标:完成UDP通信快速入门:实现1发1收。
 */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 = "我是快乐的客户端,我爱你abc".getBytes();
        DatagramPacket packet = new DatagramPacket(bytes, bytes.length
                                                   , InetAddress.getLocalHost(),  6666);

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

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

 2 服务端程序

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 len = packet.getLength();

        String rs = new String(buffer, 0 , len);
        System.out.println(rs);

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

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

9、UDP通信代码(多发多收)

需求:实现客户端不断的发数据,而服务端能不断的接收数据,客户端发送exit时客户端程序退出。

1 客户端程序

/**
 * 目标:完成UDP通信快速入门:实现客户端反复的发。
 */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地址(找到服务端主机)
               参数四:服务端程序的端口。
             */
        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);
        }
    }
}

2 服务端程序

/**
 * 目标:完成UDP通信快速入门-服务端反复的收
 */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 len = packet.getLength();

            String rs = new String(buffer, 0 , len);
            System.out.println(rs);

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

10、TCP通信(一发一收)

Java提供了一个java.net.Socket类来完成TCP通信。我们先讲一下Socket完成TCP通信的流程,再讲代码怎么编写就很好理解了。如下图所示

  1. 当创建Socket对象时,就会在客户端和服务端创建一个数据通信的管道,在客户端和服务端两边都会有一个Socket对象来访问这个通信管道。
  2. 现在假设客户端要发送一个“在一起”给服务端,客户端这边先需要通过Socket对象获取到一个字节输出流,通过字节输出流写数据到服务端
  3. 然后服务端这边通过Socket对象可以获取字节输入流,通过字节输入流就可以读取客户端写过来的数据,并对数据进行处理。
  4. 服务端处理完数据之后,假设需要把“没感觉”发给客户端端,那么服务端这边再通过Socket获取到一个字节输出流,将数据写给客户端
  5. 客户端这边再获取输入流,通过字节输入流来读取服务端写过来的数据。

07441e582c114cbca13adaf30a10ab6f.png

1 TCP客户端

6222a4d7dc4f4efb9e8230c3e8bf6b4b.png

下面我们写一个客户端,用来往服务端发数据。由于原始的字节流不是很好用,这里根据我的经验,我原始的OutputStream包装为DataOutputStream是比较好用的。

/**
 *  目标:完成TCP通信快速入门-客户端开发:实现1发1收。
 */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(); // 释放连接资源
    }
}

2 TCP服务端

ca50e09295744df9b6400d91e447d9f7.png

上面我们只是写了TCP客户端,还没有服务端,接下来我们把服务端写一下。这里的服务端用来接收客户端发过来的数据。

/**
 *  目标:完成TCP通信快速入门-服务端开发:实现1发1收。
 */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();
    }
}

11、TCP通信(多发多收)

需求:客户端能一直发消息,服务端能够一直接收消息。

1 TCP客户端

/**
 *  目标:完成TCP通信快速入门-客户端开发:实现客户端可以反复的发消息出去
 */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();
        }
    }
}

2 TCP服务端

注意:如果客户端Socket退出之后,就表示连接客户端与服务端的数据通道被关闭了,这时服务端就会出现异常。服务端可以通过出异常来判断客户端下线了,所以可以用try...catch把读取客户端数据的代码套一起来,catch捕获到异常后,打印客户端下线。


/**
 *  目标:完成TCP通信快速入门-服务端开发:实现服务端反复发消息
 */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) {
            try {
                // 5、使用数据输入流读取客户端发送过来的消息
                String rs = dis.readUTF();
                System.out.println(rs);
            } catch (Exception e) {
                System.out.println(socket.getRemoteSocketAddress() + "离线了!");
                dis.close();
                socket.close();
                break;
            }
        }
    }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值