Socket学习记录

本次学习Socket的编程开发,该技术在一些通讯软件,比如说微信,QQ等有广泛应用。

网络结构

这些都是计算机网络中的内容,我们在这里简单回顾一下:

在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述

四次握手是为了确保收发数据都已完成。

在这里插入图片描述

我们首先了解一下关于获取主机地址的相关方法:

		//获取本机IP地址对象的地址InetAddress localHost = InetAddress.getLocalHost();System.out.println(localHost.getHostName());System.out.println(localHost.getHostAddress());//获取指定IP域名的IP地址对象InetAddress ip = InetAddress.getByName("www.baidu.com");System.out.println(ip.getHostName());//输出ip主机名称System.out.println(ip.getHostAddress());//输出指定域名的ip地址//判断6秒内能否与百度联通,相当于pingSystem.out.println(ip.isReachable(6000));

在这里插入图片描述

UDP通信开发

随后我们进行客户端与服务端的数据发送与接收:
首先是客户端的定义:

		//创建客户端对象,这里可以选择使用无参构造,当然也可以指定端口进行有参构造,在不指定端口时系统会默认分配DatagramSocket socket = new DatagramSocket();//创建数据包封装对象,存储数据信息
//        public DatagramPacket(byte buf[], int offset, int length,
//        InetAddress address, int port) {
//            setData(buf, offset, length);
//            setAddress(address);
//            setPort(port);
//        }byte[] bytes = "客户端消息:我是鹏翔".getBytes();//客户端发送的数据包,需要指明接收的服务端的IP地址以及端口DatagramPacket packet =new DatagramPacket(bytes,bytes.length,InetAddress.getLocalHost(),8888);//发送数据包socket.send(packet);System.out.println("客户端数据发送完毕");socket.close();

服务端的开发设计

		System.out.println("服务端启动");//创建一个服务端对象,并指定端口DatagramSocket socket = new DatagramSocket(8888);//定义所能够接收的数据的大小byte[] buffer = new byte[1024*64];//服务器接受的数据包DatagramPacket packet = new DatagramPacket(buffer,buffer.length);//接收数据socket.receive(packet);int length = packet.getLength();String string = new String(packet.getData(), 0, length);//发送多少数据则接收多少数据System.out.println(string);socket.close();

至此,我们的客户端与服务端便开发完成了,在实验中,我们需要先启动服务端,再启动客户端。

在这里插入图片描述
至此,完成客户端与服务端的消息发送与接收。

UTP通信多发多收

但这只是完成了一次消息的发送与接收,而在实际情况中我们往往需要进行多发多收,那么该如何实现呢?
客户端设计:

public static void main(String[] args) throws IOException {System.out.println("服务端启动");//创建一个服务端对象,并指定端口DatagramSocket socket = new DatagramSocket(8888);//定义所能够接收的数据的大小byte[] buffer = new byte[1024*64];//服务器接受的数据包DatagramPacket packet = new DatagramPacket(buffer,buffer.length);while(true){socket.receive(packet);int length = packet.getLength();String string = new String(packet.getData(), 0, length);System.out.println(string);System.out.println("--------------------------");}}

客户端设计:

public static void main(String[] args) throws IOException {//创建客户端对象DatagramSocket socket = new DatagramSocket();Scanner scanner=new Scanner(System.in);while(true){System.out.println("请说:");String msg = scanner.nextLine();if ("exit".equals(msg)) {System.out.println("客户端数据发送完毕");socket.close();break;}byte[] bytes = msg.getBytes();//客户端发送的数据包,需要指明接收的服务端的IP地址以及端口DatagramPacket packet =new DatagramPacket(bytes,bytes.length,InetAddress.getLocalHost(),8888);//发送数据包socket.send(packet);}

此外,服务器是否能够接收多个客户端发送的消息呢,当然可以,只需要将客户端程序设置为允许多开即可。

在这里插入图片描述

TCP通信开发

在这里插入图片描述

public ServerSocket(int port) 为服务端程序注册端口

public Socket accept()方法:阻塞等待客户端的连接请求,一旦与某个客户端成功连接,则返回服务端这边的Socket对象。
客户端设计实现

		Socket socket = new Socket("127.0.0.1",8088);//从socket中获取一个字节输出流,用于给服务端发送OutputStream outputStream = socket.getOutputStream();//原本的字节输出流并不好用,将其封装为高级的数据输出流DataOutputStream dataOutputStream = new DataOutputStream(outputStream);//开始写数据dataOutputStream.writeUTF("我爱你!");dataOutputStream.close();socket.close();

服务端设计实现

		System.out.println("服务端启动");//创建ServerSocket对象,并指明端口号,方便接收客户端数据ServerSocket serverSocket = new ServerSocket(8088);//调用accept方法,等待客户端的连接请求Socket accept = serverSocket.accept();//从socket的通信管道中得到一个字节输入流InputStream inputStream = accept.getInputStream();//将原始的字节输入流包装成高级的数据输入流DataInputStream dataInputStream = new DataInputStream(inputStream);//使用数据输入流读取客户端发送的数据String string = dataInputStream.readUTF();//通信很严格,要保持一致System.out.println(string);System.out.println(accept.getInetAddress());//输出发送客户端的IP地址dataInputStream.close();serverSocket.close();

在这里插入图片描述

在这里插入图片描述

同样的,我们只是完成一条消息的发送与接收,那么该如何实现数据的多发多收呢?

TCP通信多发多收

其实实现与UDP时的完全相同,只需要一个循环即可。
全选要加入循环的语句,按住Ctrl+Alt+T

多发多收服务端设计:

public static void main(String[] args) throws IOException {System.out.println("服务端启动");//创建ServerSocket对象,并指明端口号,方便接收客户端数据ServerSocket serverSocket = new ServerSocket(8088);//调用accept方法,等待客户端的连接请求Socket accept = serverSocket.accept();//从socket的通信管道中得到一个字节输入流InputStream inputStream = accept.getInputStream();//将原始的字节输入流包装成高级的数据输入流DataInputStream dataInputStream = new DataInputStream(inputStream);//使用数据输入流读取客户端发送的数据while (true) {String string = dataInputStream.readUTF();//通信很严格,要保持一致System.out.println(string);System.out.println(accept.getInetAddress());//输出发送客户端的IP地址}}

多发多收客户端设计:

 public static void main(String[] args) throws IOException {//创建Socket对象,并同时请求服务端程序的连接,声明服务器的IP与端口号Socket socket = new Socket("127.0.0.1",8088);//从socket中获取一个字节输出流,用于给服务端发送OutputStream outputStream = socket.getOutputStream();//原本的字节输出流并不好用,将其封装为高级的数据输出流DataOutputStream dataOutputStream = new DataOutputStream(outputStream);//开始写数据Scanner scanner = new Scanner(System.in);while (true) {System.out.println("请输入内容:");String string = scanner.nextLine();if ("exit".equals(string)) {dataOutputStream.close();socket.close();System.out.println("退出成功!");break;}dataOutputStream.writeUTF(string);dataOutputStream.flush();//将数据刷新出去,防止数据还留在内存中}}

在这里插入图片描述

同时需要注意,TCP作为可靠连接,一旦服务端挂掉了,那么就会抛出异常

在这里插入图片描述

我们可以通过捕获抛出的异常,来判断是否客户端退出。

public class Servers {public static void main(String[] args) throws IOException {System.out.println("服务端启动");//创建ServerSocket对象,并指明端口号,方便接收客户端数据ServerSocket serverSocket = new ServerSocket(8088);//调用accept方法,等待客户端的连接请求Socket accept = serverSocket.accept();//从socket的通信管道中得到一个字节输入流InputStream inputStream = accept.getInputStream();//将原始的字节输入流包装成高级的数据输入流DataInputStream dataInputStream = new DataInputStream(inputStream);//使用数据输入流读取客户端发送的数据while (true) {try {String string = dataInputStream.readUTF();//通信很严格,要保持一致System.out.println(string);} catch (IOException e) {System.out.println(accept.getInetAddress()+"客户端退出了!");//输出发送客户端的IP地址dataInputStream.close();serverSocket.close();break;}}}
}

在这里插入图片描述

TCP通信聊天室

如何实现一个服务器与多个客户端通信呢?现在的肯定是不行的,因为我们在判断客户端关闭后也将服务端关闭了,事实上,此时服务端只能和一个客户端建立可靠连接,归根接地,是因为在建立连接后,服务端一直在等待某一个客户端发送的消息,这就导致会停留在那,从而无法与其他客户端建立连接。怎么办呢?可以使用多线程来解决。

在这里插入图片描述
改进后的服务端:

package IPAddress.TCP;import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;public class ServerMany {public static void main(String[] args) throws IOException {System.out.println("服务端启动");//创建ServerSocket对象,并指明端口号,方便接收客户端数据ServerSocket serverSocket = new ServerSocket(8088);//调用accept方法,等待客户端的连接请求Socket accept = null;while (true) {accept = serverSocket.accept();new ServerReadThread(accept).start();}}
}

多开线程实现服务端接收数据

package IPAddress.TCP;import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;public class ServerReadThread extends Thread{private Socket socket;public ServerReadThread(Socket accept) {this.socket=accept;}@Overridepublic void run() {try {InputStream inputStream = socket.getInputStream();//将原始的字节输入流包装成高级的数据输入流DataInputStream dataInputStream = new DataInputStream(inputStream);System.out.println(socket.getInetAddress()+"客户端上线了!");//输出发送客户端的IP地址//使用数据输入流读取客户端发送的数据while (true) {try {String string = dataInputStream.readUTF();//通信很严格,要保持一致System.out.println(string);} catch (IOException e) {System.out.println(socket.getInetAddress()+"客户端下线了!");dataInputStream.close();socket.close();break;}}} catch (IOException e) {System.out.println("服务异常!" + socket.getInetAddress() + "连接中断!");}}
}

在这里插入图片描述

最后,我们可以通过一个聊天室的案例来简单检验一下成果:

在这里插入图片描述
首先我们需要在服务端定义一个集合,用于保存连接的socket,同时由主线程负责创建socket连接,一旦有新的客户端开启,则开启一个新的子线程,用于该客户端与服务端之间的通信:

public class Server {public static List<Socket> sockets=new ArrayList<>();public static void main(String[] args) throws IOException {System.out.println("服务端启动");//创建ServerSocket对象,并指明端口号,方便接收客户端数据ServerSocket serverSocket = new ServerSocket(8088);//调用accept方法,等待客户端的连接请求Socket accept = null;while (true) {accept = serverSocket.accept();sockets.add(accept);new ServerReadThread(accept).start();}}
}

在服务端的子线程中,负责将接收的信息输出,并将接收的信息转发给其他客户端(端口转发)

import java.io.*;
import java.net.Socket;public class ServerReadThread extends Thread{private Socket socket;public ServerReadThread(Socket accept) {this.socket=accept;}@Overridepublic void run() {try {InputStream inputStream = socket.getInputStream();//将原始的字节输入流包装成高级的数据输入流DataInputStream dataInputStream = new DataInputStream(inputStream);System.out.println(socket.getInetAddress()+"客户端上线了哟!");//输出发送客户端的IP地址//使用数据输入流读取客户端发送的数据while (true) {try {String string = dataInputStream.readUTF();//通信很严格,要保持一致System.out.println(string);sendMsg(string);} catch (IOException e) {System.out.println(socket.getInetAddress()+"客户端下线了!");Server.sockets.remove(socket);dataInputStream.close();socket.close();break;}}} catch (IOException e) {System.out.println("服务异常!" + socket.getInetAddress() + "连接中断!");}}private void sendMsg(String string) throws IOException {//发送给所有Socket管道去接收System.out.println("转发数据");for (Socket online:Server.sockets) {OutputStream outputStream = online.getOutputStream();DataOutputStream dataOutputStream = new DataOutputStream(outputStream);dataOutputStream.writeUTF(string);dataOutputStream.flush();}}
}

在客户端设计中,除了原本的输入数据发送信息外,还要开启一个线程用于接收服务器转发的数据:

public class Clients {public static void main(String[] args) throws IOException {//创建Socket对象,并同时请求服务端程序的连接,声明服务器的IP与端口号Socket socket = new Socket("127.0.0.1",8088);new ClientReadThread(socket).start();//从socket中获取一个字节输出流,用于给服务端发送OutputStream outputStream = socket.getOutputStream();//原本的字节输出流并不好用,将其封装为高级的数据输出流DataOutputStream dataOutputStream = new DataOutputStream(outputStream);//开始写数据Scanner scanner = new Scanner(System.in);while (true) {System.out.println("请输入内容:");String string = scanner.nextLine();if ("exit".equals(string)) {dataOutputStream.close();socket.close();System.out.println("退出成功!");break;}dataOutputStream.writeUTF(string);dataOutputStream.flush();//将数据刷新出去,防止数据还留在内存中}}
}

客户端接收转发信息的线程设计如下:

public class ClientReadThread extends Thread{private Socket socket;public ClientReadThread(Socket accept) {this.socket=accept;}@Overridepublic void run() {try {InputStream inputStream = socket.getInputStream();//将原始的字节输入流包装成高级的数据输入流DataInputStream dataInputStream = new DataInputStream(inputStream);//使用数据输入流读取客户端发送的数据while (true) {try {String string = dataInputStream.readUTF();//通信很严格,要保持一致System.out.println(string);} catch (IOException e) {System.out.println("自己客户端下线了!");dataInputStream.close();socket.close();break;}}} catch (IOException e) {System.out.println("服务异常!" + socket.getInetAddress() + "连接中断!");}}
}

在这里插入图片描述

BS架构通信开发

首先了解一下BS架构的基本原理:

在这里插入图片描述
BS架构下,我们并不需要开发客户端程序。只需要开发服务端即可

public class Server {public static List<Socket> sockets=new ArrayList<>();public static void main(String[] args) throws IOException {System.out.println("服务端启动");//创建ServerSocket对象,并指明端口号,方便接收客户端数据ServerSocket serverSocket = new ServerSocket(9090);while (true) {Socket accept = serverSocket.accept();System.out.println("子线程启动");sockets.add(accept);new ServerReadThread(accept).start();}}
}

随后进行服务端子进程的设计,用于向浏览器响应一段文字,注意,要想向浏览器响应内容,就需要遵循固定的HTTP协议规定,即符合下面的要求:

在这里插入图片描述
服务端子线程设计如下:

public class ServerReadThread extends Thread{private Socket socket;public ServerReadThread(Socket accept) {this.socket=accept;}@Overridepublic void run() {try {System.out.println("上线访问了");OutputStream outputStream = socket.getOutputStream();//将原始的字节输出流包装成高级的打印流PrintStream printStream = new PrintStream(outputStream);printStream.println("HTTP/1.1 200 OK");printStream.println("Content-Type:text/html;charset=UTF-8");printStream.println();printStream.println("<div style='color:red;font-size:40px;text-align:center'>服务端响应</div>");printStream.close();socket.close();} catch (IOException e) {System.out.println("服务异常!" + socket.getInetAddress() + "连接中断!");}}
}

前面的BS架构设计中,每当浏览器发起一次访问,就会创建一个线程,然而,当我们的网站访问量十分大时,即面对一些高并发情况,就会出现宕机现象。对于这种情况,可以通过线程池来进行优化。

在这里插入图片描述

在主线程中设计一个线程池来控制线程数量

public class Server {public static List<Socket> sockets=new ArrayList<>();public static void main(String[] args) throws IOException {System.out.println("服务端启动");//创建ServerSocket对象,并指明端口号,方便接收客户端数据ServerSocket serverSocket = new ServerSocket(9090);//通过线程池来控制执行线程的数量与任务队列数量ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(16 * 2, 16 * 2,0, TimeUnit.SECONDS, new ArrayBlockingQueue<>(8),Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());while (true) {Socket accept = serverSocket.accept();System.out.println("子线程启动");threadPoolExecutor.execute(new ServerReadRunnable(accept));}}
}

将原本的线程改造为任务。

public class ServerReadRunnable implements Runnable{private Socket socket;public ServerReadRunnable(Socket accept) {this.socket=accept;}@Overridepublic void run() {try {System.out.println("上线访问了");OutputStream outputStream = socket.getOutputStream();//将原始的字节输出流包装成高级的打印流PrintStream printStream = new PrintStream(outputStream);printStream.println("HTTP/1.1 200 OK");printStream.println("Content-Type:text/html;charset=UTF-8");printStream.println();printStream.println("<div style='color:red;font-size:40px;text-align:center'>服务端响应</div>");printStream.close();socket.close();} catch (IOException e) {System.out.println("服务异常!" + socket.getInetAddress() + "连接中断!");}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/9607.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python笔记(16)模块

模块是组织代码、实现复用、提升开发效率的关键元素。它们如同积木块一样&#xff0c;构成了Python程序的基石。本 一、理解Python模块&#xff1a;定义与基本特性 1. 定义 模块&#xff0c;简单来说&#xff0c;就是包含Python定义和语句的文件。它可以是一个.py文件&#…

这是一关于DSC相关的文档

这是一关于DSC相关的文档 上面这幅图清晰的展示了somewhat flat的像素图示

机器学习算法应用——关联规则分析(4-4)

关联规则分析&#xff08;4-4&#xff09; 关联规则分析&#xff08;Association Rule Mining&#xff09;是一种基于频繁项集的分析方法&#xff0c;它以最常出现在一起的元素之间的关系作为分析对象&#xff0c;主要用于发掘大数据中隐藏的关联规则&#xff0c;是数据挖掘技术…

JAVA_1

JAVA_1 一、JAVA8种数据类型二、JAVA数据类型自动和强制转换三、JAVA运算符 一、JAVA8种数据类型 1.byte 1字节 2.short 2字节 3.int 4字节 4.long 8字节 5.float 4字节 6.double 8字节 7.char 2字节 8.boolean true和false import java.util.Scanner;public class test1_dat…

Python教程:一文了解PageObject模式

PageObject 模式是一种用于测试自动化的设计模式&#xff0c;它将页面的功能和页面的实现分开&#xff0c;提高了代码的可维护性和可重用性。本文将从基础概念开始&#xff0c;逐步介绍 Python 中的 PageObject 模式&#xff0c;并提供详细的代码示例。 1. 什么是 PageObject 模…

小众行业风口:Q1季度擦窗机器人行业线上市场销售数据分析

今天给大家分享一个2024年的小众行业增长风口——擦窗机器人。 作为家居自动化里的重要一员&#xff0c;擦窗机器人可以简称为擦窗神器&#xff0c;是为了解决大户型家庭的外窗清洁痛点而存在。而目前&#xff0c;擦窗机器人行业正在走向成熟&#xff0c;且市场需求量居高不下…

Linux专题-Makefile(1)

1.Makefile中的注释使用 # 2. Makefile中的静默执行。 makefile中&#xff0c;默认情况下执行一行命令前会先把这一行命令打印出来&#xff0c;然后再执行这条命令。如果不想看到打印的命令&#xff0c;则可以使用静默执 行的功能&#xff0c;即仅打印出命令执行的结果。使用方…

苹果公司因iPad广告争议而道歉,承认“未达标”|TodayAI

周二&#xff0c;苹果公司发布了一则新的iPad Pro广告&#xff0c;引起了广泛争议&#xff0c;该公司随后发表道歉声明&#xff0c;承认这则广告“未达标”。这则名为“压碎&#xff01;”的广告意图展示全新的M4芯片iPad Pro的创意潜力&#xff0c;但却因其表现方式而备受批评…

设计模式学习笔记 - 回顾总结:在实际软件开发中常用的设计思想、原则和模式

概述 本章&#xff0c;先来回顾下整个专栏的知识体系&#xff0c;主要包括面向对象、设计原则、编码规范、重构技巧、设计模式五个部分。 面向对象 相对于面向过程、函数式编程&#xff0c;面向对象是现在最主流的编程范式。纯面向过程的编程方法&#xff0c;现在已经不多见了…

android——关于app性能优化篇

前言 应用性能优化是指通过各种技术手段和优化策略&#xff0c;提高应用程序的性能&#xff0c;使其能够更高效地运行和响应用户操作。 下面介绍一些常见的应用性能优化方法 一、布局优化 1、减少嵌套 嵌套层数尽量少&#xff0c;使用ConstaintLayout能使层级大大降低尽量使…

浅谈如何利用 AI 提高内容生产效率?|TodayAI

在数字化时代&#xff0c;内容的创建和分发速度变得尤为关键。人工智能&#xff08;AI&#xff09;技术提供了加速这一过程的可能性&#xff0c;不仅提升了生产效率&#xff0c;还改善了内容的质量和受众的接受度。本文深入探讨AI如何在内容生成、分发与推广&#xff0c;以及内…

LangChain连接国内大模型测试|智谱ai、讯飞星火、通义千问

智谱AI 配置参考 https://python.langchain.com/v0.1/docs/integrations/chat/zhipuai/ZHIPUAI_API_KEY从https://open.bigmodel.cn/获取 from langchain_community.chat_models import ChatZhipuAI from langchain_core.messages import AIMessage, HumanMessage, SystemMes…

超越机械抓手:看多指机器人如何灵活运用触觉?

论文标题&#xff1a; Learning Visuotactile Skills with Two Multifingered Hands 论文作者&#xff1a; Toru Lin, Yu Zhang, Qiyang Li, Haozhi Qi, Brent Yi, Sergey Levine, and Jitendra Malik 1. 机器人新挑战&#xff1a;多指手指操作 在自动化和智能化日益普及的…

mybatis useGeneratedKeys=“true“ keyProperty=“id“的作用

useGeneratedKeys“true” keyProperty"id"的作用 <insert id"save" parameterType"User" useGeneratedKeys"true" keyProperty"id"></insert>作用为&#xff1a;保存成功后往User类中的id属性赋值&#xff0c;…

深度学习中超参数设置

1、batchsize 在训练深度学习模型时&#xff0c;batch size&#xff08;批大小&#xff09;和 epochs&#xff08;迭代次数&#xff09;之间的关系取决于您的数据集大小、模型复杂度、计算资源等因素。下面是一些一般性的指导原则&#xff1a; 较大的 Batch Size&#xff1a;通…

idea导入jar包、打jar包

一、导入jar包 1.在工程下面新建一个lib目录&#xff0c;将jar包放在lib目录下面 2.按步骤导入jar包 -接下来选择jar包所在的位置进行导入 -下图中标红框位置就是刚刚导入的jar包 二、直接用idea打jar包 -下图中Main Class就是选择程序中的Main函数 -右侧标红框位置表示…

VSCode Python 自动格式化代码(black)不生效

弄了很长时间&#xff0c;各种尝试&#xff0c;就想实现保存后自动格式化代码&#xff0c;用户设置&#xff0c;工作区设置&#xff0c;因为环境较多以为有啥冲突&#xff0c;就是没找到。后来看到一条评论说Python版本低&#xff0c;想到了版本问题。然后就看到以下描述 记录…

Spring如何控制Bean的加载顺序

前言 正常情况下&#xff0c;Spring 容器加载 Bean 的顺序是不确定的&#xff0c;那么我们如果需要按顺序加载 Bean 时应如何操作&#xff1f;本文将详细讲述我们如何才能控制 Bean 的加载顺序。 场景 我创建了 4 个 Class 文件&#xff0c;分别命名为 FirstInitialization Se…

maven 分离式打包

pom中插件配置&#xff1a; <!-- Maven Jar 插件配置 --> <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><configuration><archive><!-- 将类路径添加到 MANIFEST.MF 文…

python数据分析——数据的选择和运算

数据的选择和运算 前言一、数据选择NumPy的数据选择一维数组元素提取示例 多维数组行列选择、区域选择示例 花式索引与布尔值索引布尔索引示例一示例二 花式索引示例一示例二 Pandas数据选择Series数据获取DataFrame数据获取列索引取值示例一示例二 取行方式示例loc() 方法示例…