侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

mysql的udf编程之非阻塞超时重传

数据库  /  管理员 发布于 6年前   236

MySQL的UDF(User Defined Function)类似于一种API, 用户根据一定的规范用C/C++(或采用C调用规范的语言)编写一组函数(UDF),然后编译成动态链接库,通过DROP FUNCTION语句来加载和卸载UDF。UDF被加载后可以像调用MySQL的内置函数一样来调用它,并且服务器在启动时会自动加载原来存在的UDF。

复制代码 代码如下:
#ifdef STANDARD/* STANDARD is defined, don't use any mysql functions */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef __WIN__
typedef unsigned __int64 ulonglong;    /* Microsofts 64 bit types */
typedef __int64 longlong;
#else
typedef unsigned long long ulonglong;
typedef long long longlong;
#endif /*__WIN__*/
#else
#include <my_global.h>
#include <my_sys.h>
#if defined(MYSQL_SERVER)
#include <m_string.h>        /* To get strmov() */
#else
/* when compiled as standalone */
#include <string.h>
#endif
#endif
#include <mysql.h>
#include <m_ctype.h>
#include <m_string.h>
#include <stdlib.h>
#include <errno.h>
#include <netdb.h>
#include <unistd.h>
#include<fcntl.h>
#include<sys time.h="">
#include<sys ioctl.h="">
#include <sys types.h="">
#include <netinet in.h="">
#include <sys socket.h="">
#include <sys wait.h="">
#include<arpa inet.h="">
#include<unistd.h>
#include <mysql.h>
#include <ctype.h>
#ifdef HAVE_DLOPEN

my_bool http_post_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
void http_post_deinit(UDF_INIT *initid);
longlong http_post(UDF_INIT *initid, UDF_ARGS *args, char *is_null,char *error);
/*************************************************************************
** Example of init function
** Arguments:
** initid                        Points to a structure that the init function should fill.
**            char *ptr;            A pointer that the function can use.
** message                        Error message
**RETURN                        This function should return 1 if something goes wrong. In this case
**************************************************************************/
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;
}

if(args->arg_count == 4 && args->args[3]!=NULL)
{
      int flexibleLength = strlen(args->args[3]);
      if(flexibleLength > 160000)
      {
          int allocLength = 200 + flexibleLength;
          if (!(initid->ptr=(char*) malloc(allocLength) ) )
          {
                strcpy(message,"Couldn't allocate memory in http_post_init");
                return 1;
          }
        return 0;
      }
      else
      {
          initid->ptr=NULL;
    }

}
   return 0;

}

/****************************************************************************
** Deinit function. This should all resources allocated by
** this function.
** Arguments:
** initid    Return value from xxxx_init
****************************************************************************/
void http_post_deinit(UDF_INIT *initid)
{
     if (initid!=NULL && initid->ptr!=NULL)
          {
              free(initid->ptr);
              initid->ptr = NULL;
          }

}

/***************************************************************************
** UDF string function.
** Arguments:
** initid    Structure filled by xxx_init
** args        The same structure as to xxx_init. This structure
** This function should return a pointer to the result string.
** Normally this is 'result' but may also be an alloced string.
***************************************************************************/
longlong http_post(    UDF_INIT *initid, UDF_ARGS *args,
                char *is_null __attribute__((unused)),
                char *error __attribute__((unused)))
{
    int sockfd=0;
    int numbytes=0;
    int flags=0;
    int cycletimes=0;
    char* sendBuffer=NULL;

    fd_set wset;
    struct timeval tval;
    tval.tv_sec = 0;
    tval.tv_usec = 300000;

    if(initid->ptr == NULL)
    {
        char sendArray[160000] = "\0";
        sendBuffer=sendArray;
    }
    else
    {
        sendBuffer = initid->ptr;
    }

    struct sockaddr_in serv_addr;
    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);

    if(args->arg_count == 4 && (args->args[3]!=NULL) )
    {
        int argsNum = strlen(args->args[3]);
        sprintf(sendBuffer,"POST /?%s HTTP/1.1\r\nContent-Length:%d\r\n\r\n%s",args->args[2],argsNum,args->args[3]);
    }
    else
    {
        sprintf(sendBuffer,"POST /?%s HTTP/1.1\r\n",args->args[2]);
    }

    if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
    {
        close(sockfd);
        return 2;
    }
    flags = fcntl(sockfd,F_GETFL,0);
    fcntl(sockfd,F_SETFL,flags|O_NONBLOCK);//设置为非阻塞
    do
    {
        connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr));
        FD_ZERO(&wset);
        FD_SET(sockfd,&wset);
        if( select(sockfd+1, NULL, &wset, NULL,&tval) <= 0 && cycletimes==5)
        {
            close(sockfd);
            return 5;
        }
        numbytes = send(sockfd,sendBuffer,strlen(sendBuffer),0);
        if(numbytes<0)
        {
            usleep(20000);
        }
        cycletimes++;
    }while(numbytes<0 && cycletimes!=5);
    if(numbytes<0)
    {
        close(sockfd);
        return 4;
    }
    close(sockfd);
    return 0;
}
#endif /* HAVE_DLOPEN */
</ctype.h></mysql.h></unistd.h></arpa></sys></sys></netinet></sys></sys></sys></fcntl.h></unistd.h></netdb.h></errno.h></stdlib.h></m_string.h></m_ctype.h></mysql.h></string.h></m_string.h></my_sys.h></my_global.h></string.h></stdio.h></stdlib.h>


  • 上一条:
    MySQL配置文件my.cnf参数优化和中文详解
    下一条:
    使用mysql_udf与curl库完成http_post通信模块示例
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 分库分表的目的、优缺点及具体实现方式介绍(0个评论)
    • DevDB - 在 VS 代码中直接访问数据库(0个评论)
    • 在ubuntu系统中实现mysql数据存储目录迁移流程步骤(0个评论)
    • 在mysql中使用存储过程批量新增测试数据流程步骤(0个评论)
    • php+mysql数据库批量根据条件快速更新、连表更新sql实现(0个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2017-06
    • 2017-08
    • 2017-09
    • 2017-10
    • 2017-11
    • 2018-01
    • 2018-05
    • 2018-10
    • 2018-11
    • 2020-02
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-09
    • 2021-02
    • 2021-04
    • 2021-07
    • 2021-08
    • 2021-11
    • 2021-12
    • 2022-02
    • 2022-03
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-07
    • 2023-08
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-03
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客