博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
mysql中客户端连接server的三种方式
阅读量:4214 次
发布时间:2019-05-26

本文共 4103 字,大约阅读时间需要 13 分钟。

在mysqld_main函数的最后,通过下面的code来建立来自客户端的连接mysqld_socket_acceptor->connection_event_loop();  void connection_event_loop() {    Connection_handler_manager *mgr =        Connection_handler_manager::get_instance();    while (!connection_events_loop_aborted()) {      Channel_info *channel_info = m_listener->listen_for_connection_event();      if (channel_info != NULL) mgr->process_new_connection(channel_info);    }  }这里的listen_for_connection_event有三种实现分别是named_pipe/share_memory/socket_connetction.这三种分别实现在sql/Conn_handler 中,这里以socket_connetction的实现为例Channel_info *Mysqld_socket_listener::listen_for_connection_event() {#可以可以选择用poll还是select,为啥没有epoll呢?#ifdef HAVE_POLL  int retval = poll(&m_poll_info.m_fds[0], m_socket_map.size(), -1);#else  m_select_info.m_read_fds = m_select_info.m_client_fds;  int retval = select((int)m_select_info.m_max_used_connection,                      &m_select_info.m_read_fds, 0, 0, 0);#endif#retval小于零的异常情况   if (retval < 0 && socket_errno != SOCKET_EINTR) {    /*      select(2)/poll(2) failed on the listening port.      There is not much details to report about the client,      increment the server global status variable.    */    connection_errors_select++;    if (!select_errors++ && !connection_events_loop_aborted())      LogErr(ERROR_LEVEL, ER_CONN_SOCKET_SELECT_FAILED, socket_errno);  }  if (retval < 0 || connection_events_loop_aborted()) return NULL;  /* Is this a new connection request ? */#有一个新的连接,从这里知道可以同时有多个socket存在  MYSQL_SOCKET listen_sock = MYSQL_INVALID_SOCKET;  bool is_unix_socket = false;#ifdef HAVE_POLL  for (uint i = 0; i < m_socket_map.size(); ++i) {    if (m_poll_info.m_fds[i].revents & POLLIN) {      listen_sock = m_poll_info.m_pfs_fds[i];      is_unix_socket = m_socket_map[listen_sock];      break;    }  }#else   // HAVE_POLL  for (socket_map_iterator_t sock_map_iter = m_socket_map.begin();       sock_map_iter != m_socket_map.end(); ++sock_map_iter) {    if (FD_ISSET(mysql_socket_getfd(sock_map_iter->first),                 &m_select_info.m_read_fds)) {      listen_sock = sock_map_iter->first;      is_unix_socket = sock_map_iter->second;      break;    }  }#endif  // HAVE_POLL  MYSQL_SOCKET connect_sock;  struct sockaddr_storage cAddr;#同一个连接最多retry 10次  for (uint retry = 0; retry < MAX_ACCEPT_RETRY; retry++) {    socket_len_t length = sizeof(struct sockaddr_storage);#通过accept得到socket,然后再通过mysql_socket_getfd得到fd    connect_sock =        mysql_socket_accept(key_socket_client_connection, listen_sock,                            (struct sockaddr *)(&cAddr), &length);    if (mysql_socket_getfd(connect_sock) != INVALID_SOCKET ||        (socket_errno != SOCKET_EINTR && socket_errno != SOCKET_EAGAIN))      break;  }#检查是否得到fd错误  if (mysql_socket_getfd(connect_sock) == INVALID_SOCKET) {    /*      accept(2) failed on the listening port, after many retries.      There is not much details to report about the client,      increment the server global status variable.    */    connection_errors_accept++;    if ((m_error_count++ & 255) == 0)  // This can happen often      LogErr(ERROR_LEVEL, ER_CONN_SOCKET_ACCEPT_FAILED, strerror(errno));    if (socket_errno == SOCKET_ENFILE || socket_errno == SOCKET_EMFILE)      sleep(1);  // Give other threads some time    return NULL;  }  Channel_info *channel_info = NULL;#根据connect_sock 构建新的Channel_info_local_socket,并返回  if (is_unix_socket)    channel_info = new (std::nothrow) Channel_info_local_socket(connect_sock);  else    channel_info = new (std::nothrow) Channel_info_tcpip_socket(connect_sock);  if (channel_info == NULL) {    (void)mysql_socket_shutdown(connect_sock, SHUT_RDWR);    (void)mysql_socket_close(connect_sock);    connection_errors_internal++;    return NULL;  }  return channel_info;}Channel_info_local_socket  会将connect_sock 保存在m_connect_sock中class Channel_info_local_socket : public Channel_info {  // connect socket object  MYSQL_SOCKET m_connect_sock;   /**    Constructor that sets the connect socket.    @param connect_socket set connect socket descriptor.  */  Channel_info_local_socket(MYSQL_SOCKET connect_socket)      : m_connect_sock(connect_socket) {}}

 

转载地址:http://pinmi.baihongyu.com/

你可能感兴趣的文章
test-definitions/blob/master/auto-test/boost/boost.sh
查看>>
Java多态性理解
查看>>
Intellij Idea 工具在java文件中怎么避免 import .*包,以及import包顺序的问题
查看>>
IDEA Properties中文unicode转码问题
查看>>
Oracle中Blob转换成Clob
查看>>
Linux如何查看so中函数名
查看>>
自动管理代码的android.mk
查看>>
cocos2dx 2.2.6编译记录(1)
查看>>
makefile学习网站
查看>>
C 编写lua模块(1)
查看>>
Lua教程:Lua调用C/C++函数(4)
查看>>
win下创建win32控制台工程,执行lua脚本
查看>>
cocos2dx android启动错误
查看>>
eclipse: android rename package name
查看>>
cocos2dx c++调用java思想
查看>>
cocos2dx lua Node节点 私有数据存取
查看>>
lua math.ceil math.ceil
查看>>
cocos2dx CCNode计算node的大小
查看>>
cocos2dx 布局记录(1)
查看>>
lua 多行注释和取消多行注释
查看>>