mysql server 源码分析_Mysql源代码分析—网络初始化 | 学步园

//这些比较简单,看看注释就能明白了

/*初始化网络,主要是初始化网络监听的套接字ip_socket和用于本地监听的unix_sock*/

static void network_init(void)

{

struct sockaddr_in IPaddr;

#ifdef HAVE_SYS_UN_H

struct sockaddr_un UNIXaddr;

#endif

int arg=1;

int ret;

uint waited;

uint this_wait;

uint retry;

DBUG_ENTER("network_init");

LINT_INIT(ret);

/*设置端口*/

set_ports();

if (mysqld_port != 0 && !opt_disable_networking && !opt_bootstrap)

{

DBUG_PRINT("general",("IP Socket is %d",mysqld_port));

/*初始化本地服务器的监听套接字*/

ip_sock = socket(AF_INET, SOCK_STREAM, 0);

if (ip_sock == INVALID_SOCKET)

{

DBUG_PRINT("error",("Got error: %d from socket()",socket_errno));

sql_perror(ER(ER_IPSOCK_ERROR)); /* purecov: tested */

unireg_abort(1); /* purecov: tested */

}

/*进行本地地址绑定*/

bzero((char*) &IPaddr, sizeof(IPaddr));

IPaddr.sin_family = AF_INET;

IPaddr.sin_addr.s_addr = my_bind_addr;

IPaddr.sin_port = (unsigned short) htons((unsigned short) mysqld_port);

#ifndef __WIN__

/*

We should not use SO_REUSEADDR on windows as this would enable a

user to open two mysqld servers with the same TCP/IP port.

*/

/*windows允许使用端口复用*/

(void) setsockopt(ip_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,sizeof(arg));

#endif /* __WIN__ */

/*

Sometimes the port is not released fast enough when stopping and

restarting the server. This happens quite often with the test suite

on busy Linux systems. Retry to bind the address at these intervals:

Sleep intervals: 1, 2, 4, 6, 9, 13, 17, 22, ...

Retry at second: 1, 3, 7, 13, 22, 35, 52, 74, ...

Limit the sequence by mysqld_port_timeout (set --port-open-timeout=#).

*/

/*不断进行绑定,除非超时或者绑定成功*/

for (waited= 0, retry= 1; ; retry++, waited+= this_wait)

{

if (((ret= bind(ip_sock, my_reinterpret_cast(struct sockaddr *) (&IPaddr),

sizeof(IPaddr))) >= 0) ||

(socket_errno != SOCKET_EADDRINUSE) ||

(waited >= mysqld_port_timeout))

break;

sql_print_information("Retrying bind on TCP/IP port %u", mysqld_port);

/*计算下一次尝试绑定的间隔*/

this_wait= retry * retry / 3 + 1;

sleep(this_wait);

}

if (ret < 0)

{

DBUG_PRINT("error",("Got error: %d from bind",socket_errno));

sql_perror("Can't start server: Bind on TCP/IP port");

sql_print_error("Do you already have another mysqld server running on port: %d ?",mysqld_port);

unireg_abort(1);

}

/*设置队列长度*/

if (listen(ip_sock,(int) back_log) < 0)

{

sql_perror("Can't start server: listen() on TCP/IP port");

sql_print_error("listen() on TCP/IP failed with error %d",

socket_errno);

unireg_abort(1);

}

}

#ifdef __NT__

/* create named pipe */

/*创建命名管道*/

if (Service.IsNT() && mysqld_unix_port[0] && !opt_bootstrap &&

opt_enable_named_pipe)

{

pipe_name[sizeof(pipe_name)-1]= 0; /* Safety if too long string */

strxnmov(pipe_name, sizeof(pipe_name)-1, "\\\\.\\pipe\\",

mysqld_unix_port, NullS);

bzero((char*) &saPipeSecurity, sizeof(saPipeSecurity));

bzero((char*) &sdPipeDescriptor, sizeof(sdPipeDescriptor));

if (!InitializeSecurityDescriptor(&sdPipeDescriptor,

SECURITY_DESCRIPTOR_REVISION))

{

sql_perror("Can't start server : Initialize security descriptor");

unireg_abort(1);

}

if (!SetSecurityDescriptorDacl(&sdPipeDescriptor, TRUE, NULL, FALSE))

{

sql_perror("Can't start server : Set security descriptor");

unireg_abort(1);

}

saPipeSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);

saPipeSecurity.lpSecurityDescriptor = &sdPipeDescriptor;

saPipeSecurity.bInheritHandle = FALSE;

if ((hPipe= CreateNamedPipe(pipe_name,

PIPE_ACCESS_DUPLEX,

PIPE_TYPE_BYTE |

PIPE_READMODE_BYTE |

PIPE_WAIT,

PIPE_UNLIMITED_INSTANCES,

(int) global_system_variables.net_buffer_length,

(int) global_system_variables.net_buffer_length,

NMPWAIT_USE_DEFAULT_WAIT,

&saPipeSecurity)) == INVALID_HANDLE_VALUE)

{

LPVOID lpMsgBuf;

int error=GetLastError();

FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |

FORMAT_MESSAGE_FROM_SYSTEM,

NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),

(LPTSTR) &lpMsgBuf, 0, NULL );

sql_perror((char *)lpMsgBuf);

LocalFree(lpMsgBuf);

unireg_abort(1);

}

}

#endif

#if defined(HAVE_SYS_UN_H)

/*创建UNIX域套接字*/

/*

** Create the UNIX socket

*/

/*Unix域套接字不能是匿名的*/

if (mysqld_unix_port[0] && !opt_bootstrap)

{

DBUG_PRINT("general",("UNIX Socket is %s",mysqld_unix_port));

if (strlen(mysqld_unix_port) > (sizeof(UNIXaddr.sun_path) - 1))

{

sql_print_error("The socket file path is too long (> %u): %s",

(uint) sizeof(UNIXaddr.sun_path) - 1, mysqld_unix_port);

unireg_abort(1);

}

/**/

if ((unix_sock= socket(AF_UNIX, SOCK_STREAM, 0)) < 0)

{

sql_perror("Can't start server : UNIX Socket "); /* purecov: inspected */

unireg_abort(1); /* purecov: inspected */

}

/*绑定的本地地址*/

bzero((char*) &UNIXaddr, sizeof(UNIXaddr));

UNIXaddr.sun_family = AF_UNIX;

strmov(UNIXaddr.sun_path, mysqld_unix_port);

(void) unlink(mysqld_unix_port);

(void) setsockopt(unix_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,

sizeof(arg));

umask(0);

/*绑定本地地址*/

if (bind(unix_sock, my_reinterpret_cast(struct sockaddr *) (&UNIXaddr),

sizeof(UNIXaddr)) < 0)

{

sql_perror("Can't start server : Bind on unix socket"); /* purecov: tested */

sql_print_error("Do you already have another mysqld server running on socket: %s ?",mysqld_unix_port);

unireg_abort(1); /* purecov: tested */

}

umask(((~my_umask) & 0666));

#if defined(S_IFSOCK) && defined(SECURE_SOCKETS)

(void) chmod(mysqld_unix_port,S_IFSOCK); /* Fix solaris 2.6 bug */

#endif

/*设置队列*/

if (listen(unix_sock,(int) back_log) < 0)

sql_print_warning("listen() on Unix socket failed with error %d",

socket_errno);

}

#endif

DBUG_PRINT("info",("server started"));

DBUG_VOID_RETURN;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值