0

0

MySQL 服务器监听客户端连接源码

php中文网

php中文网

发布时间:2016-06-07 17:01:48

|

1089人浏览过

|

来源于php中文网

原创

在下面的代码有,有些结构体还不清楚,如THD,st_vio,pollfd等。但可以看出MySQL使用Select模型来接收客户端的连接。而且也在网上

在下面的代码有,有些结构体还不清楚,如THD,st_vio,pollfd等。但可以看出MySQL使用Select模型来接收客户端的连接。而且也在网上查清,unix_sock是指同一机器中不同进程间的通信,如命名管道。而ip_sock指的是不同主机间的通信。

void handle_connections_sockets()

{

  my_socket UNINIT_VAR(sock), UNINIT_VAR(new_sock);

  uint error_count=0;

  THD *thd;

  struct sockaddr_storage cAddr;

  int ip_flags=0,socket_flags=0,flags=0,retval;

  st_vio *vio_tmp;

#ifdef HAVE_POLL

  int socket_count= 0;

  struct pollfd fds[2]; // for ip_sock and unix_sock

#else

  fd_set readFDs,clientFDs;

  uint max_used_connection= (uint) (max(ip_sock,unix_sock)+1);

#endif

 

  DBUG_ENTER("handle_connections_sockets");

 

#ifndef HAVE_POLL

  FD_ZERO(&clientFDs);

#endif

 

  if (ip_sock != INVALID_SOCKET)

  {

#ifdef HAVE_POLL

    fds[socket_count].fd= ip_sock;

    fds[socket_count].events= POLLIN;

    socket_count++;

#else

    FD_SET(ip_sock,&clientFDs);

#endif   

#ifdef HAVE_FCNTL

    ip_flags = fcntl(ip_sock, F_GETFL, 0);

#endif

  }

#ifdef HAVE_SYS_UN_H

#ifdef HAVE_POLL

  fds[socket_count].fd= unix_sock;

  fds[socket_count].events= POLLIN;

  socket_count++;

#else

  FD_SET(unix_sock,&clientFDs);

#endif

#ifdef HAVE_FCNTL

  socket_flags=fcntl(unix_sock, F_GETFL, 0);

#endif

#endif

 

  DBUG_PRINT("general",("Waiting for connections."));

  MAYBE_BROKEN_SYSCALL;

  while (!abort_loop)

  {

#ifdef HAVE_POLL

    retval= poll(fds, socket_count, -1);

#else

    readFDs=clientFDs;

 

    retval= select((int) max_used_connection,&readFDs,0,0,0);//等待客户端连接,反回错误或有连接到来

#endif

 

    if (retval

    {

DM6在线读报系统
DM6在线读报系统

DM6在线读报系统ASPX 免费版2.0。如果您是一个DM广告公司的网站管理员,正在寻求一套程序或源码可以让公司网站具有一套配合网站整体架构的电子杂志频道,那您现在可找对了。请仔细阅读以下关于DM6在线读报系统的说明。 这是一个网站用户可以直接在线阅读报纸且无需插件(连Flash都不用)、无需下载、无需安装的在线读报系统(服务器端模块),通过将此系统放到网站文件目录中即可轻松生成网站的在线读报频道

下载

      if (socket_errno != SOCKET_EINTR)

      {

    if (!select_errors++ && !abort_loop)    /* purecov: inspected */

      sql_print_error("mysqld: Got error %d from select",socket_errno); /* purecov: inspected */

      }

      MAYBE_BROKEN_SYSCALL

      continue;

    }

 

    if (abort_loop)

    {

      MAYBE_BROKEN_SYSCALL;

      break;

    }

 

    /* Is this a new connection request ? */

#ifdef HAVE_POLL

    for (int i= 0; i

    {

      if (fds[i].revents & POLLIN)//读取事件类型

      {

        sock= fds[i].fd;

#ifdef HAVE_FCNTL

        flags= fcntl(sock, F_GETFL, 0);

#else

        flags= 0;

#endif // HAVE_FCNTL

        break;

      }

    }

#else  // HAVE_POLL

#ifdef HAVE_SYS_UN_H

    if (FD_ISSET(unix_sock,&readFDs))

    {

      sock = unix_sock;

      flags= socket_flags;

    }

    else

#endif // HAVE_SYS_UN_H

    {

      sock = ip_sock;

      flags= ip_flags;

    }

#endif // HAVE_POLL

 

#if !defined(NO_FCNTL_NONBLOCK)

    if (!(test_flags & TEST_BLOCKING))

    {

#if defined(O_NONBLOCK)

      fcntl(sock, F_SETFL, flags | O_NONBLOCK);//设置为非阻塞模式

#elif defined(O_NDELAY)

      fcntl(sock, F_SETFL, flags | O_NDELAY);

#endif

    }

#endif /* NO_FCNTL_NONBLOCK */

    for (uint retry=0; retry

    {

      size_socket length= sizeof(struct sockaddr_storage);

      new_sock= accept(sock, (struct sockaddr *)(&cAddr),//接受连接,连接使用阻塞方式

                       &length);

      if (new_sock != INVALID_SOCKET ||

      (socket_errno != SOCKET_EINTR && socket_errno != SOCKET_EAGAIN))

    break;

      MAYBE_BROKEN_SYSCALL;

#if !defined(NO_FCNTL_NONBLOCK)

      if (!(test_flags & TEST_BLOCKING))

      {

    if (retry == MAX_ACCEPT_RETRY - 1)

      fcntl(sock, F_SETFL, flags);      // Try without O_NONBLOCK

      }

#endif

    }

#if !defined(NO_FCNTL_NONBLOCK)

    if (!(test_flags & TEST_BLOCKING))

      fcntl(sock, F_SETFL, flags);

#endif

    if (new_sock == INVALID_SOCKET)

    {

      if ((error_count++ & 255) == 0)        // This can happen often

    sql_perror("Error in accept");

      MAYBE_BROKEN_SYSCALL;

      if (socket_errno == SOCKET_ENFILE || socket_errno == SOCKET_EMFILE)

    sleep(1);               // Give other threads some time

      continue;

    }

 

#ifdef HAVE_LIBWRAP

    {

      if (sock == ip_sock)

      {

    struct request_info req;

    signal(SIGCHLD, SIG_DFL);

    request_init(&req, RQ_DAEMON, libwrapName, RQ_FILE, new_sock, NULL);

    my_fromhost(&req);

    if (!my_hosts_access(&req))//判断主机是否具有访问权限

    {//如果主机没有被赋予给予权限,,则拒绝连接

      /*

        This may be stupid but refuse() includes an exit(0)

        which we surely don't want...

        clean_exit() - same stupid thing ...

      */

      syslog(deny_severity, "refused connect from %s",

         my_eval_client(&req));

 

      /*

        C++ sucks (the gibberish in front just translates the supplied

        sink function pointer in the req structure from a void (*sink)();

        to a void(*sink)(int) if you omit the cast, the C++ compiler

        will cry...

      */

      if (req.sink)

        ((void (*)(int))req.sink)(req.fd);

 

      (void) shutdown(new_sock, SHUT_RDWR);//关闭连接

      (void) closesocket(new_sock);

      continue;

    }

      }

    }

#endif /* HAVE_LIBWRAP */

 

    {

      size_socket dummyLen;

      struct sockaddr_storage dummy;

      dummyLen = sizeof(dummy);

      if (  getsockname(new_sock,(struct sockaddr *)&dummy,

                  (SOCKET_SIZE_TYPE *)&dummyLen)

      {

    sql_perror("Error on new connection socket");

    (void) shutdown(new_sock, SHUT_RDWR);

    (void) closesocket(new_sock);

    continue;

      }

    }

 

    /*

    ** Don't allow too many connections

    */

 

    if (!(thd= new THD))//为该连接分配处理的结构,在以后用于给线程使用

    {

      (void) shutdown(new_sock, SHUT_RDWR);

      (void) closesocket(new_sock);

      continue;

    }

    if (!(vio_tmp=vio_new(new_sock,

              sock == unix_sock ? VIO_TYPE_SOCKET :

              VIO_TYPE_TCPIP,

              sock == unix_sock ? VIO_LOCALHOST: 0)) ||

    my_net_init(&thd->net,vio_tmp))//初始化网络

    {

      /*

        Only delete the temporary vio if we didn't already attach it to the

        NET object. The destructor in THD will delete any initialized net

        structure.

      */

      if (vio_tmp && thd->net.vio != vio_tmp)

        vio_delete(vio_tmp);

      else

      {

    (void) shutdown(new_sock, SHUT_RDWR);

    (void) closesocket(new_sock);

      }

      delete thd;

      continue;

    }

    if (sock == unix_sock)

      thd->security_ctx->host=(char*) my_localhost;

 

    create_new_thread(thd);//准备为连接分配线程

  }

  DBUG_VOID_RETURN;

}

linux

相关专题

更多
vlookup函数使用大全
vlookup函数使用大全

本专题整合了vlookup函数相关 教程,阅读专题下面的文章了解更多详细内容。

26

2025.12.30

金山文档相关教程
金山文档相关教程

本专题整合了金山文档相关教程,阅读专题下面的文章了解更多详细操作。

28

2025.12.30

PS反选快捷键
PS反选快捷键

本专题整合了ps反选快捷键介绍,阅读下面的文章找到答案。

25

2025.12.30

表格中一行两行的方法
表格中一行两行的方法

本专题整合了表格中一行两行的相关教程,阅读专题下面的文章了解更多详细内容。

3

2025.12.30

cpu温度过高解决方法大全
cpu温度过高解决方法大全

本专题整合了cpu温度过高相关教程,阅读专题下面的文章了解更多详细内容。

5

2025.12.30

ASCII码介绍
ASCII码介绍

本专题整合了ASCII码相关内容,阅读专题下面的文章了解更多详细内容。

31

2025.12.30

GPS是什么
GPS是什么

本专题整合了GPS相关内容,阅读专题下面的文章了解更多详细内容。

3

2025.12.30

wifi拒绝接入
wifi拒绝接入

本专题整合了wifi拒绝接入相关教程,阅读下面的文章了解更多详细方法。

9

2025.12.30

丰网速运介绍
丰网速运介绍

本专题整合了丰网速运查询入口以及相关内容,阅读专题下面的文章了解更多内容。

3

2025.12.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 0.6万人学习

Node.js 教程
Node.js 教程

共57课时 | 7.6万人学习

CSS3 教程
CSS3 教程

共18课时 | 4.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号