如何使用mysql的 c API 函数mysql

如何使用mysql的 c API 函数mysql,第1张

MYSQL_OPT_READ_TIMEOUT 是 MySQL c api 客户端中用来设置读取超时时间的参数。在 MySQL 的官方文档中,该参数的描述是这样的:

MYSQL_OPT_READ_TIMEOUT (argument type: unsigned int *)The timeout in seconds for each attempt to read from the server. There are retries if necessary, so the total effective timeout value is three times the option value. You can set the value so that a lost connection can be detected earlier than the TCP/IPClose_Wait_Timeout value of 10 minutes.

也就是说在需要的时候,实际的超时时间会是设定值的 3 倍。但是实际测试后发现实际的超时时间和设置的超时时间一致。

而具体什么时候发生三倍超时,在文档中没有找到。所以对 MySQL 5.7.20 的源码进行了一些分析。

使用 GDB 调试代码找了实际与 mysql server 通信的代码,如下:

其中 vio_read() 函数中,使用 recv 和 poll 来读取报文和做读取超时。net_should_retry() 函数只有在发生 EINTR 时才会返回 true。从这段代码来看是符合测试结果的,并没有对读取进行三次重试。只有在读取 *** 作被系统中断打断时才会重试,但是这个重试并没有次数限制。

从上面代码的分析可以看出,代码的逻辑和文档的描述不符。于是在一顿搜索后,找到了一个 MySQL 的 BUG(Bug #31163)。该 BUG 报告了在 MySQL 5.0 中,MySQL c api 读取的实际超时时间是设置的三倍,与现有文档描述相符。于是对 MySQL 5.0.96 的代码又进行分析。

同样使用 GDB 找到了通信部分的代码。这次找到了重试三次的代码,如下:

这个版本的 MySQL api 的读写超时是直接使用的 setsockopt 设置的。第一次循环,在 A 点发生了第一次超时(虽然注释写的非阻塞,但是客户端的连接始终是阻塞模式的)。然后在 B 点将该 socket 设置为阻塞模式,C 点这里重置 retry 次数。由于设置了 alarm 第二次以后的循环会直接进入 D 点的这个分支,并且判断循环次数。作为客户端时net->retry_count 始终是 1,所以重试了两次,共计进行了 3 次 vioread 后从 E 点退出函数。

由上面的分析可知,MySQL 文档对于该参数的描述已经过时,现在的 MYSQL_OPT_READ_TIMEOUT 并不会出现三倍超时的问题。而 Bug #31163 中的处理结果也是将文档中该参数的描述更新为实际读取超时时间是设定时间的三倍。也许是 MySQL 的维护者们在后续版本更新时忘记更新文档吧。

你下个API就知道了

/*************************************************************************

PROGRAM: rsimple

FILE: rsimple.c

PURPOSE: Shows how to find all the data notes (documents) in a Domino

database and read the fields with simple data types.

SYNTAX:rsimple <database>

or

rsimple

COMMENTS:

This program uses the API function NSFSearch() to find all the

data notes in the given database. For each data note that it

finds, this reads several fields of simple data types and prints

their values to the screen.

*************************************************************************/

/* C include files */

#include <stdio.h>

#include <string.h>

/* Lotus C API for Domino and Notes include files */

#include <global.h>

#include <nsfdb.h>

#include <nsfnote.h>

#include <nsfsearc.h>

#include <osmem.h>

#include <nsferr.h>

#include <osmisc.h>

#if defined(OS390)

#include <_Ascii_a.h> /* NOTE: must be the LAST file included */

#include <lapicinc.h>

#endif /* OS390 */

void LNPUBLIC ProcessArgs (int argc, char *argv[],

char *db_filename)

void PrintAPIError (STATUS)

#define STRING_LENGTH 256

/* Function prototypes */

STATUS LNPUBLIC print_fields (void far *, SEARCH_MATCH far *,

ITEM_TABLE far *)

/************************************************************************

FUNCTION: main

************************************************************************/

int main(int argc, char *argv[])

{

char *db_filename /* pathname of source database */

DBHANDLEdb_handle /* handle of source database */

char *formula /* an ASCII selection formula */

FORMULAHANDLEformula_handle /* a compiled selection formula */

WORD wdc /* a word we don't care about */

STATUS error = NOERROR /* return status from API calls */

char database_name[STRING_LENGTH]

db_filename = database_name

ProcessArgs(argc, argv, db_filename)

if (error = NotesInitExtended (argc, argv))

{

printf("\n Unable to initialize Notes.\n")

return (1)

}

/* Open the database. */

if (error = NSFDbOpen (db_filename, &db_handle))

{

PrintAPIError (error)

NotesTerm()

return (1)

}

/* Write an ASCII selection formula. */

formula = "@All"

/* Compile the selection formula. */

if (error = NSFFormulaCompile (

NULL, /* name of formula (none) */

(WORD) 0, /* length of name */

formula,/* the ASCII formula */

(WORD) strlen(formula),/* length of ASCII formula */

&formula_handle,/* handle to compiled formula */

&wdc, /* compiled formula length (don't care) */

&wdc, /* return code from compile (don't care) */

&wdc, &wdc, &wdc, &wdc)) /* compile error info (don't care) */

{

NSFDbClose (db_handle)

PrintAPIError (error)

NotesTerm()

return (1)

}

方法/步骤

1

【首先】

1.如果想快速开发,没有自己的服务器,还是推荐使用云API的数据云。 2.不使用云API的数据云,可能是因为有web版且已经有商用数据。 3.不使用云API的数据云,需自己写数据接口,即客户端发送请求接收处理与生成json数据给客户端进行交互。 4.感谢APICloud提供新的APP开发方式。 其实也不难,使用api.ajax进行请求即可。PHPer,以下使用演示使用PHP,数据库使用Mysql,JAVA党或者.NET党请自行coding...

2

【连接到数据库(文件放在服务器上),服务器端输出JSON】

<?php

/*

* 配置连接数据库信息

*/

$host='localhost'//主机

$user='root'//数据库账号

$password=''//数据库密码

$database='test'//数据库名

//打开数据库连接

$db=mysqli_connect($host,$user,$password,$database)

//判断连接是否成功

if($db){

$db->query("set names utf8")//设置UTF-8编码(JSON的唯一编码)

}else{

echo 'DATABASE_CONNECTION_DIE'//数据库连接失败

exit

}

//sql查询语句

$sql="select id,name,sex,age from person"

$result=$db->query($sql)

while($row=$result->fetch_assoc()){

$person_info[]=$row//将取得的所有数据赋值给person_info数组

}

echo json_encode($person_info)//输出JSON

?>

复制代码

输出的JSON示例:

[{"id":"1","name":"\u54c8\u5c3c","sex":"\u7537","age":"22"},{"id":"2","name":"\u5c0f\u9648","sex":"\u5973","age":"21"},{"id":"3","name":"\u5c0f\u767d","sex":"\u672a\u77e5","age":"1"}]

复制代码

3

【测试用的数据库SQL语句】

--

-- Database: `test`

--

-- --------------------------------------------------------

--

-- 表的结构 `person`

--

CREATE TABLE IF NOT EXISTS `person` (

`id` int(11) NOT NULL,

`name` varchar(5) NOT NULL,

`sex` varchar(2) NOT NULL,

`age` int(3) NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8

--

-- 转存表中的数据 `person`

--

INSERT INTO `person` (`id`, `name`, `sex`, `age`) VALUES

(1, '哈尼', '男', 22),

(2, '小陈', '女', 21),

(3, '小白', '未知', 1)

复制代码

搞定服务器端输出JSON后,重点来了...

4

【端API使用api.ajax读取接口数据】

<!DOCTYPE HTML>

<html>

<head>

<meta charset="utf-8">

<meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/>

<title>test</title>

</head>

<body>

<button onclick="showPersonInfo()">点我获取数据</button>

</body>

<script type="text/javascript" src="../script/api.js"></script>

<script>

function showPersonInfo(){

api.showProgress()//显示加载进度框

//使用api.ajax请求数据,具体使用方法和参数请看官方文档,这里使用get方法演示

api.ajax({

url:'http://192.168.0.10/get.php',//如果地址访问不到会请求出错,请填写自己的接口地址

method:'get',

cache:'false',

timeout:30,

dataTpye:'json',

},function(ret,err){

api.hideProgress()//隐藏加载进度框

if(ret){

for(var i=0i<ret.lengthi++){

var html='<br>'+'ID:'+ret[i].id+'<br>'+'姓名:'+ret[i].name+'<br>'+'性别:'+ret[i].sex+'<br>'+'年龄'+ret[i].age

document.write(html)

}

}else{

api.alert({msg:('错误码:'+err.code+';错误信息:'+err.msg+'网络状态码:'+err.statusCode)})

}

})

}

</script>

</html>

复制代码

5

OK,如果要POST方式,请自行参考官方文档。

思路就是这样,其它的依此类推:

客户端发送请求,服务器端接收处理后返回数据。

用户登录和状态检查推荐使用token检验,不要直接post密码。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/9999075.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-04
下一篇 2023-05-04

发表评论

登录后才能评论

评论列表(0条)

保存