10.2.1 服务端流程分析

本文详细介绍了SSL服务器端的主要流程,包括初始化SSL服务器证书、启动服务线程、接收客户端消息线程处理和发送消息到客户端的步骤。涉及到SSL上下文设置、证书与私钥匹配、Windows Socket初始化、TCP端口绑定、监听连接以及SSL连接的建立与数据交换。
摘要由CSDN通过智能技术生成

  服务端主要包括以下主要函数过程:初始化SSL服务器证书函数、启动服务线程函数、接收客户端消息线程处理函数、发送消息到客户端函数。

1.初始化SSL服务器证书

此过程的代码添加在OnInitDialog方法中。

处理过程如下:

1)初始化OpenSSL算法库

        SSL_load_error_strings();

         SSLeay_add_ssl_algorithms();

2)初始化SSL服务器端协议算法

        meth = SSLv23_server_method();    //使用SSL V2V3协议

         ctx = SSL_CTX_new (meth);               //初始化SSL上下文

3)设置服务器证书

        SSL_CTX_use_certificate_file(ctx, CERTF, SSL_FILETYPE_PEM);

4)设置服务器私钥

 SSL_CTX_use_PrivateKey_file(ctx, KEYF, SSL_FILETYPE_PEM);

5)检查服务器私钥和证书是否匹配

         if (!SSL_CTX_check_private_key(ctx))

         {

                   return FALSE;

         }

6)初始化保存客户端链接的全局变量数组

        for(int i=0;i<MAX_CLIENT;i++)

         {

                   Clients[i].fd=0;

                   Clients[i].ssl=NULL;

         }

处理流程如图所示:

2.启动服务线程处理函数

启动服务的线程函数void StartServer(void* void_parm),通过CreateThread函数调用。StartServer函数处理过程如下:

1)初始化Windows Socket

         if (WSAStartup(MAKEWORD(1, 1), &wsaData))

         {

                   char *msg = (char *)malloc(128);

                   strcpy(msg,"初始化Socket失败!");

                   SendMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_CLIENT_MSG,0,(long )msg);

                   return;

         }

2)初始化sockaddr_in结构体,设置TCP协议和端口

        memset (&sa_serv, '/0', sizeof(sa_serv));

         sa_serv.sin_family      = AF_INET;

         sa_serv.sin_addr.s_addr = INADDR_ANY;

         sa_serv.sin_port        = htons (port);

3)绑定端口

        err = bind(listen_sd, (struct sockaddr*) &sa_serv,sizeof (sa_serv));   

4)侦听TCP链接

        err = listen (listen_sd, 5);

5)启动接收连接线程

        for(;;)

         {

                   //启动接收连接线程

                   hd=CreateThread(NULL,0,

                            (LPTHREAD_START_ROUTINE)AcceptThreadProc,

                            (void *)listen_sd, 0 ,&idThread);

                   //等待该线程执行完毕,开启下一个线程,继续等待接收连接。

                   WaitForSingleObject(hd, INFINITE);

          }

其处理过程流程图如图所示:

    

3.接收客户端消息线程处理函数

接收客户端消息线程处理函数void client( void* void_parmint )。处理过程如下:

1)新建SSL链接句柄

if((ssl = SSL_new(ctx)) == NULL)

         {

                   return;

         }

2)设置SSL链接Socket句柄

SSL_set_fd(ssl, clientFd);

3)接收SSL链接,并把客户端链接句柄保存到全局变量中。

         if(SSL_accept(ssl) <= 0)

         {

                   return;

         }

         for(int i=0;i<MAX_CLIENT;i++)

         {

                   if(Clients[i].fd==0)

                   {

                            Clients[i].fd=clientFd;

                            Clients[i].ssl=ssl;

                            flag = 1;

                            break;

                   }

         }

4)异步select方式等待客户端数据

         for(;;)

         {

                   FD_ZERO(&writeFds);

                   FD_ZERO(&readFds);

                   FD_ZERO(&excFds);

                   FD_SET(clientFd, &readFds);

                   //异步的方式等待客户端数据

                   int nfd = select(maxFd + 1, &readFds, &writeFds, &excFds, NULL);

                   。。。

         }

5)如果有数据,则读取客户端数据

         if(FD_ISSET(clientFd, &readFds))//有客户端数据需要读取

         {

                   //接收客户端数据

                  len = SSL_read(clientDesc.ssl,buffer,sizeof(buffer));

                            。。。

         }

6)把客户端消息显示在窗口列表库中

         SendMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_CLIENT_MSG,clientFd,(long )msg);

其处理过程流程图如图所示:

4.发送消息到客户端函数

发送到客户端只要调用SSL_write函数即可。在void CServerDlg::OnSend()函数中向已经链接的所有客户端发送消息。

         for(int i=0;i<MAX_CLIENT;i++)

         {

                   if(Clients[i].fd != 0)

                   {

                            //发送消息

                            SSL_write(Clients[i].ssl,m_str.GetBuffer(0),m_str.GetLength());

                            m_str.ReleaseBuffer();

                   }

         }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值