该图是一个TCP连接发送的数据包
一、先搞明白几个问题
为什么需要有三次握手?
客户端和服务端传送数据之前需要建立一个TCP连接,建立连接时两个端点之间一共需要交换3个数据段,通过三次握手来处理来避免连接错误。
为什么会用到套接字?
mysql服务端通过系统调用socket来创建一个套接字,它是系统单独分配给mysql进程称为文件描述符的资源。凭借这种机制,客户端和服务端程序可以通过它跨网通信。
如何实现一个服务端套接字连接?
mysql服务使用socket函数创建一个未命名的套接字。接下来使用bind函数命名套接字,这样将特定端口号(3306)的连接转到对应的mysql服务。然后使用listen函数,创建一个队列来存放客户端连接。再使用accept函数接受处理客户端连接。最后使用read/write函数进行读写操作。
poll函数是做什么用的?
它是IO多路复用的一种方法。调用poll()能够判断一堆TCP连接是否来了数据,有数据的话再调用recfrom()将数据从内核复制到用户空间。
二、模拟MySQL 客户端连接server
#include <stdlib.h>
#include <stdio.h>
#include "mysql.h"
int main(int argc, char *argv[]){
MYSQL *conn;
unsigned int timeout = 10;
conn = mysql_init(NULL);
mysql_options(conn, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&timeout);
mysql_options(conn, MYSQL_INIT_COMMAND, "SET autocommit=1");
if (!mysql_real_connect(conn, "localhost", "wanzhao", "wanzha123", "wanzhao", 0, NULL, 0)) {
printf("Create connection failed\n");
printf("Connection error:%s", mysql_error(conn));
}
mysql_close(conn);
return 1;
}
进行编译
gcc -I/work/soft/mysql/mysqlbug/include c_connct.c -L/work/soft/mysql/mysqlbug/lib -lmysqlclient -o c_connct
复制
三、理解客户端和MySQL server三次握手的流程
客户端和MySQL server三次握手的流程
四、MySQL server三次握手的函数栈
// jy 初始化连接接受器
mysqld_socket_acceptor->init_connection_acceptor()
// jy 初始化listener,调用socket|bind函数|listen函数
Mysqld_socket_listener::setup_listener
// jy 接受连接开始处理
Connection_acceptor<Mysqld_socket_listener>::connection_event_loop
// jy 监听套接字从客户端接收连接事件,调用poll|accept函数来实现
Mysqld_socket_listener::listen_for_connection_event
inline_mysql_socket_accept
复制
复制
Channel_info* Mysqld_socket_listener::listen_for_connection_event()
{
#ifdef HAVE_POLL
//jy 检测多个数据报套接字已经就绪
int retval= poll(&m_poll_info.m_fds[0], m_socket_map.size(), -1);
#endif
......
for (uint retry= 0; retry < MAX_ACCEPT_RETRY; retry++)
{
socket_len_t length= sizeof(struct sockaddr_storage);
//jy inline_mysql_socket_accept调用accept函数,接受连接
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;
}
复制
文章转载自万照,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。