因为数据库所有的操作都需要从客户端通过网络发送到数据库后台,网络是数据库开始的地方,所以这里先研究网络通信模块VIO。
网络通信无非需要下面几个接口:
建立连接
发送数据
读取数据
断开连接
释放资源
相关结构体
VIO类型
VIO_TYPE_TCPIP TCP/IP通信方式
VIO_TYPE_SOCKET UNIX下的SOCKET通信方式
VIO_TYPE_NAMEDPIPE 命名管道通信方式
VIO_TYPE_SSL SSL通信方式
VIO_TYPE_SHARED_MEMORY 共享内存通信方式
VIO结构
该结构体主要用于和数据库建立连接,不管是client还是server,建立连接的时候都需要用到此结构体。
typedef struct st_vio Vio;
struct st_vio{
MYSQL_SOCKET mysql_socket; /*Instrumented socket */
my_bool localhost; /* Arewe from localhost? */
struct sockaddr_storage local; /* Localinternet address */
struct sockaddr_storage remote; /* Remoteinternet address */
int addrLen; /* Length of remote address */
enum enum_vio_type type; /* Type ofconnection */
my_bool inactive; /* Connection inactive (has been shutdown) */
char desc[VIO_DESCRIPTION_SIZE];/* Description string. This member MUST NOT be used directly, but only via function "vio_description" */
char *read_buffer; /* buffer forvio_read_buff */
char *read_pos; /* start ofunfetched data in the read buffer */
char *read_end; /* end ofunfetched data */
int read_timeout; /* Timeout value(ms) for read ops. */
int write_timeout; /* Timeout value(ms) for write ops. */
/* VIO vtable interface to be implemented byVIO's like SSL, Socket,Named Pipe, etc.*/
/* viodelete is responsible for cleaning upthe VIO object by freeing internal buffers, closing descriptors,handles.*/
void (*viodelete)(Vio*);
int (*vioerrno)(Vio*);
size_t (*read)(Vio*, uchar *, size_t);
size_t (*write)(Vio*, const uchar *, size_t);
int (*timeout)(Vio*, uint, my_bool);
int (*viokeepalive)(Vio*,my_bool);
int (*fastsend)(Vio*);
my_bool (*peer_addr)(Vio*, char *, uint16*, size_t);
void (*in_addr)(Vio*, struct sockaddr_storage*);
my_bool (*should_retry)(Vio*);
my_bool (*was_timeout)(Vio*);
/* vioshutdown is resposnible toshutdown/close the channel, so that no further communications can take place,however any related buffers,descriptors, handles can remain validafter a shutdown.*/
int (*vioshutdown)(Vio*);
my_bool (*is_connected)(Vio*);
my_bool (*has_data)(Vio*);
int (*io_wait)(Vio*, enum enum_vio_io_event, int);
my_bool (*connect)(Vio*, struct sockaddr *, socklen_t,int);
#ifdef _WIN32
OVERLAPPED overlapped;
HANDLE hPipe;
#endif
#ifdef HAVE_OPENSSL
void *ssl_arg;
#endif
#ifdef HAVE_SMEM
HANDLE handle_file_map;
char *handle_map;
HANDLE event_server_wrote;
HANDLE event_server_read;
HANDLE event_client_wrote;
HANDLE event_client_read;
HANDLE event_conn_closed;
size_t shared_memory_remain;
char *shared_memory_pos;
#endif /* HAVE_SMEM */
};
vio.c
vio_init
参数:
vio:需要填充的Vio结构体指针
type:VIO类型
sd:SOCKET
flags:一些标识
描述:给Vio结构体填充默认值
初始化一个vio结构,将其中的属性根据type和flags进行填充,并且将sd设置到vio结构上。
vio_reset
重置Vio结构体,只有VIO_TYPE_TCPIP和VIO_TYPE_SOCKET两种Vio类型才支持此操作。
mysql_socket_vio_new
申请一个Vio,并初始化以后返回其指针。
vio_timeout
给Vio设置超时
vio_delete
删除一个Vio连接,必须等到其完成以后再释放掉资源。
vio_end
清除内存环境,当一个连接结束的时候
viopipe.c
给windows环境增加管道通信方式。管道其实是一个只能顺序写和顺序读的文件,起主要调用Windows的API中WriteFile和ReadFile实现,由于Windows上的File相关API操作都是异步的,所以还需要一个等到异步完成的操作
vio_is_connected_pipe
建立一个管道连接
vio_is_write _pipe
往管道中写数据
vio_is_read _pipe
从管道中读数据
vio_shutdown_pipe
关闭一个管道通信
wait_overlapped_result
等到一个异步IO的完成
vioshm.c
从名字可以看出来,该文件中实现vio share memory的通信方式,简写方式是单词开头的辅音的组合。其中设计了五个Event,分别用于:
等待建立连接
等待服务器数据写完
等待服务器数据读完
等待客户端数据写完
等待客户端数据读完
vio_is_connected_shared_memory
建立shm的连接,这里其实就是简单的等到一个信号,等带其它进程Signal次信号,从而建立连接。
vio_read_shared_memory
等待读数据的时候,要同时监听两个Event,分别是服务器端wrote和close事件。
读完数据以后,要通过Event通知服务器端,数据已经读完。
vio_write_shared_memory
写完数据以后,也要同时监听两个Event,分别是服务器端read和close事件。
vio_shutdown_shared_memory
发送关闭信号,关闭连接
vio_delete_shared_memory
释放资源,释放五个Event
由于时间原因,socket和ssl方式的Vio先不介绍了,看一下代码都挺简单,以后再续!




