安卓APP简单后端的搭建
写在前面:
此教程没有用到后端框架.只是单纯用servlet做一个例子,如果是学框架可以不用往下看了
本文适合哪些人:懂java的,会写android单机程序,懂得用HTTPClient等发送请求解析请求的但对服务器搭建这一块不是特别懂的
这里整个文章以一个简单的登录注册功能为例子,是我自己学的时候做的小例子,做个记录,有错误还请指正
1,云服务器的搭建,这里我们选择阿里云服务器,各位学生朋友可以购买学生套餐,9.9每个月
购买+远程连接:教程不细说,https://blog.csdn.net/zhaoyanga14/article/details/52876838这里讲得很详细
好像没有把Windows更新关掉的都会遇到无法连接的问题,别急,问题不大,解决办法在这里,win10家庭版用户特别得看看https://www.cnblogs.com/Yintianhao/p/9199331.html
2,ubuntu云服务器的相关配置,之前我用的是WindowsServer,但是我后来从意识到Windowsserver的坑的地方,所以说时隔几个月回来再更
Windowsserver没有ubuntu的方便,而且他的图形桌面很占用资源,影响性能,ok
首先需要两个工具,一个是Xshell,一个是Xftp
Xshell用来连接远程ubuntu并从当终端的作用,Xftp用来将本地的文件传送到ubuntu,这两个是都可以在官网下载,不需要FQ
之后准备好jdk,到java官网下好jdk,记住是for linux,并且32位还是64位要搞清楚(可以去阿里云控制台看)
之后用Xftp连接服务器,将下载好的tar.gz文件传到上面,然后放在你自己想设定的目录,当然,放在最开始的目录也没问题
进入到你想要安装的目录,比如/home/ubuntu,用cd /home/ubuntu
输入命令:tar zxvf JDK压缩包名字
在这时候需要配置环境变量,最好在root环境下
命令:vim /etc/profile
在文件后面也就是fi后面加上
export JAVA_HOME=你的jdk安装目录 export CLASSPATH=$JAVA_HOME/lib/ export PATH=$PATH:$JAVA_HOME/bin export PATH JAVA_HOME CLASSPATH
之后,按esc,输入冒号,再输入x,(即保存退出)
之后还需要一个命令:source /etc/profile
没问题之后,输入java -version检测是否安装成功
(1)首先需要下载Linux版本的Tomcat(下载后缀名是tar.zip)
这里的话,你想用tomcat7或者tomcat8都随自身的需求来进行即可,没有什么硬性规定。
(2)将下载好的Tomcat移动到Linux服务器上
关于,如何从windows将文件移动(复制)到Linux系统上,这其实有很多的方法,在安装JDK的知识点中,就已经介绍了这个,不明白的请查看上面知识点。
关于上传的路径的话,传到自己喜欢的路径就好了,不过建议一般是放在/usr/这个目录下,而我这里是在/usr/下面创建了一个新的目录叫做tomcat.
(3)在服务器上解压上传的Tomcat压缩包
使用命令:taz zxvf xxxxxxxxxxx.tar.zip
备注:这个解压的话,是在你上传后的那个路径下进行解压即可,当然也可以将个这个文件拷贝到自己想改变的目录下,然后再解压,这也是没问题的。而我这里是解压到/usr/tomcat/目录下。
(4)启动tomcat
进入到安装的tomcat的目录下的bin目录
比如:我自己的:cd /home/ubuntu/apache-tomcat-8.5.24/bin
然后直接运行 ./startup.sh,看到这个说明没问题
之后可以检测一下是否能访问,到自己电脑上浏览器输入你的服务器的ip地址:8080
如果出现这画面说明没问题
不成功的话,而且之前配置没问题的话,大概是服务器没有配置安全组,所以去阿里云控制台为服务器配置安全组,端口设8080就可以了
最后,mysql的安装
这里推荐一个比较好的教程吧,我自己配的过程中也除了很多问题,慢点跟着这个来不会出问题
https://blog.csdn.net/samllwind/article/details/80508089
最后可以利用Xftp将打包好的war包部署到服务器,程序编写可以参考下面NetBeans编写Javaweb
编写
用IDEA
老实说从NetBeans到IDEA简直爽爆了...学生可以去申请IDEA的免费版
之后点next,取好名字,然后点击finish
目录结构如图所示
跟NetBeans一样,导包,点击File->ProjectStructure,然后
导完包后,需要配置Tomcat,因为项目都是先本地测试,所以本地记得安上Tomcat
配置Tomcat
然后配置本地Tomcat
之后配置名字和tomcat所在路径
这些配置好之后,就可以跑了,跟NetBeans差不多,不赘述了
本地测试没问题之后再上传服务器部署就ok
用NetBeans
第一个servlet的编写,相信在这之前应该都知道servlet这个东西,她就是把我们请求做处理然后返回给我们的东西,但是单独的它写出来是不能用的,我们需要把他放在tomcat这个容器里面,即部署,然后tomcat监听服务器的8080端口来接收我们的请求然后交给servlet处理,然后再做出回应,这里编写它是在我们的电脑上编写,不是在服务器.远程操控服务器的效率并不高...之前看某篇博客就看到有搞错了的,这里提醒一下
由于我是看着别人的教程来学的,所以我IDE也是跟着来的,没有用IDEA,编写servlet的工具用NetBeans,ok,开始
打开NetBeans,新建项目
项目名自己定
选择服务器为tomcat
点击下一步,会看到这些.这些是框架,鉴于刚学习.就跳过吧,不选任何东西
然后完成,会看到工程目录
然后我们需要创建一个配置文件,web.xml
MLGB死活截屏不好屏...我口述吧,右键点击工程名,新建一个标准部署描述符,就会看到这个,点击完成就ok
是不是以为现在可以编码了?不,我们还需要做一些准备
因为这个例子肯定会涉及到数据库操作,那么mysql-connector必定少不了,还有其他包,要将他们导入到我们的工程中才能对数据进行操作
方便大家,我将那几个包打包了一下,链接:https://pan.baidu.com/s/1zSZXmMIQQJXTuoBsFAc4sw 密码:fbyp
不过今天先不导入这些包,先暂时熟悉一下部署操作.包的操作在之后的更新中会添加进去的
ok,现在准备编码了,先创建好一个java包,右键点击"源包"文件夹,然后选择java包,一般包名为com.公司名.组名.应用名,这个我们暂且不讨论...
点击完成,在这个包底下又新建我们今天的主角servlet
命名
不要急着完成.........点击下一步,把这个勾上
可以看到NetBeans已经自动将它配置到刚才我们新建的web.xml里面了
现在进入我们的servlet里面
先不看前面的一堆吧,看这个东西,我说明了一下
熟悉HTML的大概知道了这个内容是什么了,这里干脆就看一下他返回的吧,我今晚大概是更不完了,因为明天还要课程设计....
顺便练习一下简单的部署
我们原封不动这个项目,将这个项目构建一下,右键点击工程名构建项目
然后在工程目录下的dist文件夹里面找到war文件
之后将这个文件传到远程服务器tomcat目录下面的webapps文件夹里面,重启tomcat,传的话因为之前有一个共享文件夹所以很方便了
这是部署之后
重启tomcat可以点击bin文件夹里面的startup也可以在之前安的XAMPP里面安装,ok,试一下自己的劳动成果
进入浏览器,输入你的云服务器的IP地址:8080/WebApplication2/TestServlet看看会出现什么,虽然只可能不是你想要的东西,可是
这的确是我们的服务端返回来的,事实上,我之前也是说了,熟悉HTML的就看出来了,在servlet那个out.println()的操作里面,其实就是一个静态网页hhh
ok,分割线,先更到这里
6/29 20:27继续更:
正式开始编写自己的Servlet
因为登录注册实际上就是查询数据库跟存数据库的过程,肯定是要用到数据库的,而这里的开发语言用的也是java,所以JDBC少不了
第一步就是在之前的项目里导入这些包了
首先在工程目录下创建一个lib文件夹,并将那几个包放进去
在工程里引入
在这之后我们需要创建我们的数据库,然后创建一个User表,表里面创建三个字段,一个ID,表示行的标号,一个UserName,表示用户名,一个PassWord,表示密码,这里就不用到加密了,能用就行
哦对,这里最好下一个navicat或者MySQLfront,这样创建库更方便
建议先存一两个测试用户放里面
之后我们就可以开始写servlet了,这里需要懂得一点java操作数据库的基本方法,可以参考这https://www.cnblogs.com/Yintianhao/p/9190110.html
这里我直接上代码吧
登录Servlet:LoginServlet.java
import java.sql.*; import java.util.ArrayList; import java.util.List; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Vector; import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.SQLException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class HelloForm */ @WebServlet("/HelloForm") public class TestServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public TestServlet() { super(); try { Class.forName("com.mysql.jdbc.Driver"); //驱动数据库 System.out.println("mysql run success"); } catch(java.lang.ClassNotFoundException e) { e.printStackTrace(); } // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 设置响应内容类型 response.setContentType("text/html;charset=UTF-8"); //连接数据库所需要的管理员名字和密码 String user="root"; String Upassword=""; String url = "jdbc:mysql://localhost:3306/myfirstapp?user="+user+"&password="+Upassword+"&useUnicode=true&characterEncoding=utf-8"; Connection connection = null; PrintWriter out = response.getWriter(); try{ connection = (Connection)DriverManager.getConnection(url); }catch(SQLException e1){ out.println(e1.getMessage()); e1.printStackTrace(); } //这里采用的是先从里面将所有记录取出然后找对应来验证的,实际开发中不可取,推荐使用select语句,更好 int i; Boolean flag = true; String sql = "select UserName,PassWord from user;"; try { Vector<String> userVector = new Vector<String>(); Vector<String> passwordVector = new Vector<String>(); PreparedStatement ps = (PreparedStatement) connection.prepareStatement(sql); ResultSet rs = ps.executeQuery(sql); while(rs.next()) { userVector.add(rs.getString(1)); passwordVector.add(rs.getString(2)); } for(i = 0;i<userVector.size();i++) { if(userVector.get(i).equals(request.getParameter("name"))&&passwordVector.get(i).equals(request.getParameter("password"))) {//括号里的name和password是发送URL中的 out.println("success");//如果存在这个用户,返回这个字符串 flag = false; } } if(i==userVector.size()&&flag) { out.println("failed");否则返回failed } } catch (SQLException e1) { out.println(e1.getMessage()); e1.printStackTrace(); } } // 处理 POST 方法请求的方法 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
之后就是注册模块了,原理比较简单就是存数据库
RegisterServlet.java
import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * * @author 31786 */ public class RegisterServlet extends HttpServlet { /** * Processes requests for both HTTP <code>GET</code> and <code>POST</code> * methods. * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ public RegisterServlet(){ try { Class.forName("com.mysql.jdbc.Driver"); System.out.println("mysql run success"); } catch(java.lang.ClassNotFoundException e) { e.printStackTrace(); } } protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); String user="root"; String Upassword=""; String url = "jdbc:mysql://localhost:3306/myfirstapp?user="+user+"&password="+Upassword+"&useUnicode=true&characterEncoding=utf-8"; Connection connection = null; PrintWriter out = response.getWriter(); try{ connection = (Connection)DriverManager.getConnection(url); }catch(SQLException e1){ out.println(e1.getMessage()); e1.printStackTrace(); } //+getCount(queryCount)+",\""+request.getParameter("name")+"\""+request.getParameter("password")+"\"" String queryCount = "select * from user;"; String value = String.valueOf(getCount(queryCount,connection)+1)+",\'"+request.getParameter("name")+"\',"+"\'"+request.getParameter("password")+"\'"; String sql = "insert into user(Id,UserName,PassWord) Values("+value+");"; System.out.println("sql="+sql); try{ PreparedStatement ps = (PreparedStatement) connection.prepareStatement(sql); int i = ps.executeUpdate(); if(i == 1){ out.println("success");//插入成功 }else{ out.println("failed");//插入失败 } }catch(SQLException e){ // System.out.println("sql="+sql); out.println(e.getMessage()+"sql="+sql); } } //求插入的记录的ID public int getCount(String sql,Connection connection) { int count=0; try { PreparedStatement ps = (PreparedStatement) connection.prepareStatement(sql); ResultSet rs = ps.executeQuery(); while(rs.next()) { count++; } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return count; } // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code."> /** * Handles the HTTP <code>GET</code> method. * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Handles the HTTP <code>POST</code> method. * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Returns a short description of the servlet. * * @return a String containing servlet description */ @Override public String getServletInfo() { return "Short description"; }// </editor-fold> }
ok,还是之前的步骤,清除并构建,然后部署,再测试一下,浏览器网址输入框输入云服务器IP地址:8080/WebApplication2/LoginServlet?name=Jack&password=1234567890
一不下心少打了一个c,不过可以看到,这的确是登录成功了
好了,进入最后的一个阶段,就是跟客户端对接了,相信界面啥的都没问题了,这里我贴上登录的的代码吧,采用HTTPClient的
package com.example.oshomework; import android.content.Intent; import android.content.SharedPreferences; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; public class Login extends AppCompatActivity { EditText user; EditText password; Button login; Button register; private Handler handler = new Handler() { public void handleMessage(Message msg) { String str = (String) msg.obj; Log.d("信息",str); switch (str){ case "LoginSuccess": Toast.makeText(Login.this,"登录成功",Toast.LENGTH_SHORT).show(); Intent intent = new Intent(Login.this,ShowChoices.class);//后面的ShowChoice自己实现就行 startActivity(intent); break; case "LoginFailed": Toast.makeText(Login.this,"登录失败",Toast.LENGTH_SHORT).show(); break; case "RegisterSuccess": Toast.makeText(Login.this,"注册成功",Toast.LENGTH_SHORT).show(); break; case "RegisterFailed": Toast.makeText(Login.this,"注册失败",Toast.LENGTH_SHORT).show(); break; default:break; } }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); user = (EditText) findViewById(R.id.account); password = (EditText) findViewById(R.id.password); login = (Button) findViewById(R.id.login); register = (Button) findViewById(R.id.register); login.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d("登录按钮","监听器"); Log.d(user.getText().toString(),password.getText().toString()); new Thread(){ @Override public void run() { Log.d("登录进程","....."); Message msg = new Message(); String url1 = "http://你的云服务器IP:8080/TomcatTest/TestServlet?name="+user.getText().toString()+"&password="+password.getText().toString(); try { Log.d("请求处理",url1); URL url = new URL(url1); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(2000); InputStream in = connection.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(in)); String line = null; StringBuilder builder = new StringBuilder(); while((line=reader.readLine())!=null){ builder.append(line); } if (builder.toString().equals("sucess")){ Log.d("返回",builder.toString()); msg.obj = "LoginSuccess"; handler.sendMessage(msg); }else{ //Toast.makeText(Login.this,"登录失败",Toast.LENGTH_SHORT).show(); msg.obj = "LoginFailed"; handler.sendMessage(msg); Log.d("返回了",builder.toString()); } }catch (MalformedURLException e){ Log.d("出错了","********1"); e.printStackTrace(); }catch (IOException e1){ Log.d("出错了","*********2"); e1.printStackTrace(); } } }.start(); } }); register.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //网络请求不能在主线程里进行 new Thread(){ public void run(){ Message msg = new Message(); String url1 = "http://你服务器的IP地址:8080/TomcatTest/RegisterServlet?name="+user.getText().toString()+"&password="+password.getText().toString(); try { Log.d("进程里面",url1); URL url = new URL(url1); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(2000); InputStream in = connection.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(in)); String line = null; StringBuilder builder = new StringBuilder(); while((line=reader.readLine())!=null){ builder.append(line); } if (builder.toString().equals("success")){ Log.d(builder.toString(),builder.toString()); msg.obj = "RegisterSuccess"; handler.sendMessage(msg); }else{ msg.obj = "RegisterFailed"; handler.sendMessage(msg); } }catch (MalformedURLException e){ Log.d("出错了","********1"); e.printStackTrace(); }catch (IOException e1){ Log.d("出错了","*********2"); e1.printStackTrace(); } } }.start(); } }); } }
看一下我自己这里的效果
好了,到此,简单的后端搭建基本到与客户端的对接全部完成,但后面还有更多的值得学习....
安卓APP简单后端的搭建的更多相关文章
- [编译] 6、开源两个简单且有用的安卓APP命令行开发工具和nRF51822命令行开发工具
星期四, 27. 九月 2018 12:00上午 - BEAUTIFULZZZZ 一.前言 前几天给大家介绍了如何手动搭建安卓APP命令行开发环境和nRF51822命令行开发环境,中秋这几天我把上面篇 ...
- 如何做个简单安卓App流程
有同学做毕业设计,问怎样做个简单安卓App流程,我是做服务端的,也算是经常接触app,想着做app应该很简单吧,不就做个页面,会跳转,有数据不就行了,我解释了半天,人家始终没听懂,算了,我第二天问了下 ...
- [编译] 5、在Linux下搭建安卓APP的开发烧写环境(makefile版)—— 在Linux上用命令行+VIM开发安卓APP
星期三, 19. 九月 2018 02:19上午 - BEAUTIFULZZZZ 0)前言 本文不讨论用IDE和文本编辑器开发的优劣,是基于以下两点考虑去尝试用命令行编译安卓APP的: 了解安卓APP ...
- 无框架完整搭建安卓app及其服务端(一)
技术背景: 我的一个项目做的的是图片处理,用 python 实现图片处理的核心功能后,想部署到安卓app中,但是对于一个对安卓和服务器都一知半解的小白来说要现学的东西太多了. 而实际上,我们的项目要求 ...
- [编译] 7、在Linux下搭建安卓APP的开发烧写环境(makefile版-gradle版)—— 在Linux上用命令行+VIM开发安卓APP
April 18, 2020 6:54 AM - BEAUTIFULZZZZ 目录 0 前言 1 gradle 安装配置 1.1 卸载系统默认装的gradle 1.2 下载对应版本的二进制文件 1.3 ...
- 使用VS2017开发安卓app(1)环境搭建
本人新手,边学习边写笔记,有错误不足之处,望各位博友指正~ 想要用vs开发安卓app,需要在安装时勾选 Xamarin是一个跨平台开发框架.在这一框架内,开发iOS.Android.Windows P ...
- html+css+js+Hbuilder开发一款安卓APP,根本不用学Android开发!
我们知道,要做一款安卓APP,咱们得先学安卓开发语言,例如java,前端后端.那么没有这些开发语言基础,咱们怎么做呢?其实现在有比较好的开发方案就是做webAPP,咱们可以用web前端知识构建安卓客户 ...
- 当前主流的安卓APP开发IDE
什么是主流的开发安卓APP的方式? 我是去年4月份接触的Android开发,因此特别有感触,可以明显的感受到安卓APP主流开发方式的改变. 去年,2015年年初,各大安卓开发群大部分大牛在用Eclip ...
- [技术博客]Django框架-后端的搭建
目录 Django框架-后端的搭建 前言 环境的部署 项目的创建 app的使用 创建app 修改配置文件 app中数据表的构建 前端接口 接口的路径 运行服务器 验证后端 Django框架-后端的搭建 ...
随机推荐
- 微信小程序toast框的使用
1.wx.showToast() 方法可以配置toast框的提示文字,消失的时间,显示的图标 wx.showToast({ title: '请链接网络', icon:"none", ...
- 检索 COM 类工厂中 CLSID 为 {10021F00-E260-11CF-AE68-00AA004A34D5} 的组件失败,原因是出现以下错误: 80040154 没有注册类 (异常来自 HRESULT:0x80040154 (REGDB_E_CLASSNOTREG))。
ASP.NET利用SQLDMO可以实现在线备份.还原数据库等各种功能. 由于客户的数据库和WEB服务不再同一台服务器,把网站部署在服务器上以后,运行程序,提示如下错误 当使用Interop.SQLDM ...
- 更改Ubuntu默认python版本的两种方法python-> Anaconda
当你安装 Debian Linux 时,安装过程有可能同时为你提供多个可用的 Python 版本,因此系统中会存在多个 Python 的可执行二进制文件.一般Ubuntu默认的Python版本都为2. ...
- Windows下Python安装: requires numpy+mkl 和ImportError: cannot import name NUMPY_MKL
最近写了一篇关于“微软开源分布式高性能GB框架LightGBM安装使用”的文章,有小伙伴安装Python环境遇到了问题.我个人也尝试安装了一下,确实遇到了很多问题."Windows7下pyt ...
- SDIBT 2345 (3.2.1 Factorials 阶乘)
Description N的阶乘写作N!表示小于等于N的所有正整数的乘积.阶乘会很快的变大,如13!就必须用32位整数类型来存储,70!即使用浮点数也存不下了.你的任务是找到阶乘最后面的非零位.举个例 ...
- Ubuntu安装spyder并添加快捷方式
Ubuntu安装spyder并添加快捷方式 之前通过 sudo apt install spyder sudo apt install spyder3 安装spyder,但是这样有个坏处,编译器只能用 ...
- noip第21课作业
1. 遍历二叉树 [问题描述] 以先序的方式建立一棵二叉树,空结点用‘#’号表示,例如:abd###ce##f##,将建立一棵如下的二叉树: 输出其中序序列和后序序列,其中总结点个数不超过100. 输 ...
- gradle构建工具入门
实际设置:系统变量新建: PATH新加: 查看是否安装成功:
- 王家林系列之scala--第69讲:Scala并发编程react、loop代码实战详解
刚才看了一下,群里王家林老师又更新课程了,真为王老师的勤奋感到佩服,于是迫不及待的下载下来观看学习.本期讲的是关于scala并发编程的react.loop代码实战. 信息来源于 DT大数据梦工厂微信公 ...
- 3、利用GDB进行程序调试
本文将用一个实际例子讲解如何通过GDB进行程序调试. 首先,我们需要理解的是GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具,其产生和调试的目的是让调试者知道,程序在执行时内部发生了什么 ...