- A+
显示不全请点击全屏阅读
/*首先参考mysql官方提供的udf_example.c文件,将需要include的代码复制过来,然后就可以根据需要编写自己的函数了。
我这里给出的示例是一个向指定ip和端口,post数据的例子,然后用网络调试助手进行测试。
首先根据示例中的指示,需要建立3个函数分别是初始化函数,执行函数,还有反初始化函数。
首先对这三个函数进行声明。如下:*/
my_bool http_post_init(UDF_INIT *initid, UDF_ARGS *args, char *message);//args是sql语句传回的参数,message是返回出错信息使用这些都是规定好的。
longlong http_post(UDF_INIT *initid, UDF_ARGS *args, char *is_null,char *error);//主函数体
void http_post_deinit(UDF_INIT *initid);//反初始化函数体
/*其中http_post_init需要返回my_bool型。这个函数目的是给用户提供一个方式,检验由mysql参数传进来的数据是否正确,如果正确则对其进行
主函数执行,否则程序结束。
另外mysqludf中暂时不支持在主函数体内申请内存,所以如果有要申请内存的操作,需要放在初始化过程中。但请注意,在udf中好像对于
申请和释放内存不是线程安全的,我的程序在多线程运行状态下,会发生free出错的情况,应该是多次free出错,但我在程序中只free了一次。
所以建议大家不要使用,如果需要空间较大,就建立一个大一点的静态空间吧(数组)。另外申请空间时需要使用mysqludf提供的变量名,
initid->ptr,代码示例如下,然后在主程序中直接使用initid->ptr,最后在http_post_deinit中进行释放。具体看udf_example.c*/
if (!(initid->ptr=(char*) malloc(100) ) )
{
strcpy(message,”Couldn’t allocate memory 100″);
return 1;
}
*/
return 0;
/*我的代码最终没有采用事先分配内存的方式,而是准备在主函数中申请空间。这里需要注意,成功一定要返回0,这也是udf接口规定的,如果
mysql发现返回值是1,程序立刻结束。*/
my_bool http_post_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
if (args->arg_count < 3 )
{
strcpy(message,”Wrong arguments to http_post; “);
return 1;
}
return 0;
}
//接下来具体实现函数,其目的是接收传入的ip,端口号 和数据标签,数据,该ip和端口号post数据。其中args是传入的参数,也是
//sql语句中传入的参数。
longlong http_post(UDF_INIT *initid, UDF_ARGS *args,
char *is_null __attribute__((unused)),
char *error __attribute__((unused)))
{
int sockfd=0,numbytes=0;
struct sockaddr_in serv_addr;
//int flags;
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(atoi(args->args[1]));
serv_addr.sin_addr.s_addr = inet_addr(args->args[0]);
bzero(&(serv_addr.sin_zero),8);
char sendData[128000] = “\0”;
if(args->arg_count == 4 && (args->args[3]!=NULL) )
{
int argsNum = strlen(args->args[3]);
sprintf(sendData,”POST /?%s HTTP/1.1\r\nContent-Length:%d\r\n\r\n%s”,args->args[2],argsNum,args->args[3]);
}
else
{
sprintf(sendData,”POST /?%s HTTP/1.1\r\n”,args->args[2]);
}
if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
{
close(sockfd);
return 1;
//exit();
}
if(connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) == -1)
{
close(sockfd);
return 1;
//exit();
}
if((numbytes = send(sockfd,sendData,strlen(sendData),0)) == -1)
{
close(sockfd);
return 1;
// exit();
}
close(sockfd);
return 0;
}
//由于我没有申请空间(melloc),所以我的反初始化函数为空
void http_post_deinit(UDF_INIT *initid)
{
}
//将程序保存为http_post.c编译如下(请根据机器上的mysql路径进行调整):
gcc -wall -I/usr/local/webserver/mysql/include/mysql/ -shared http_post.c -o http_post.so -fPIC//使用mysql提供的头文件生成动态链接库
cp -f http_post.so /usr/local/webserver/mysql/lib/mysql/plugin/http_post.so //将生成的.so文件放入mysql的plugin文件夹下
//进入mysql对动态链接库中的函数进行安装
cd /usr/local/webserver/mysql/bin/mysql
./mysql
//在mysql命令行下输入如下命令:
mysql> DROP FUNCTION IF EXISTS http_post;
//其目的是如果系统内安装了同名函数先进性drop。
mysql> CREATE FUNCTION http_post RETURNS INTEGER SONAME ‘http_post.so’;
//生成http_post函数,并指明调用来源是http_post.so。
//最后调用函数,其目的是向指定ip和端口发送post数据。调用前先打开指定ip主机上的网络调试助手,并监听3888端口。
mysql> select http_post(‘192.168.138.20′,’3888′,’content=insert’,’aaabbf’);
//在网络助手中显示:
POST /?content=insert HTTP/1.1
Content-Length:6
aaabbf
//程序运行成功。
Tags:
如果您喜欢我的博客,欢迎点击图片定订阅到邮箱 也可以点击链接【订阅到鲜果】
如果我的想法或工具帮助到了你,也可微信扫下方二维码打赏本人一杯咖啡