10.2.2 客户端流程分析

来源:互联网 发布:网络热门流行歌曲 编辑:程序博客网 时间:2024/06/10 09:54

    客户端主要包括以下主要函数过程:初始化SSL算法函数、连接并接收服务器消息线程函数、向服务器发送消息函数。

1.初始化SSL算法

此过程的代码添加在OnInitDialog方法中。处理过程如下:

1)初始化OpenSSL算法库

        SSL_load_error_strings();

         SSLeay_add_ssl_algorithms();

2)初始化SSL客户端协议算法

        ctx = SSL_CTX_new (SSLv23_client_method());//设置SSL协议版本

其处理流程图如图所示:

2.连接并接收服务器消息线程函数

连接服务器端,并接收服务器端消息的线程处理函数void ClientThreadProc(void* void_parm)。通过CreateThread调用该函数。其处理过程如下:

1)初始化Windows Socket环境

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

         {

                   return;

         }

2)初始化sockaddr_in结构体,设置服务器地址和端口。

        //新建socket

         sd = socket (AF_INET, SOCK_STREAM, 0);

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

         //设置服务端IP地址、和端口

         sa.sin_family      = AF_INET;

         sa.sin_addr.s_addr = dwIP;

         sa.sin_port        = htons(8443);

3)连接服务器。

        err = connect(sd, (struct sockaddr*) &sa,sizeof(sa));  

4)新建SSL连接句柄。

        ssl = SSL_new (ctx);

5)设置socket句柄到SSL句柄。

        SSL_set_fd (ssl, sd);

6)建立SSL链接。

        err = SSL_connect (ssl);

7)调用select异步等待服务器端消息。

        for(;;)

         {

                   FD_ZERO(&writeFds);

                  FD_ZERO(&readFds);

                   FD_ZERO(&excFds);

                   FD_SET(sd, &readFds);

                   //select 异步等待服务器

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

8)读取服务器消息,并显示到窗口。

        if(FD_ISSET(sd, &readFds))

                   {

                            //接收服务器消息

                            int len = SSL_read(ssl,buffer,sizeof(buffer));

                            if(len <=0)

                            {

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

                                     strcpy(msg,"服务器退出!");

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

                                     return;

                            }

                            buffer[len]='/0';

                            char *msg = (char *)malloc(len +1);

                            strcpy(msg,buffer);

                            //通过WM_CLIENT_MSG消息,发送到主窗体           SendMessage(AfxGetMainWnd()->GetSafeHwnd(),WM_CLIENT_MSG,sd,(long )msg);

                   }

其处理过程如图所示:

   

3.向服务器端发送消息函数

直接调用SSL_write,向服务器发送消息。在void CClientDlg::OnSend()函数添加如下代码:

         if(client.fd !=0)

         {

                   //发送消息

                   SSL_write(client.ssl,m_str.GetBuffer(0),m_str.GetLength());

                   m_str.ReleaseBuffer();

         }

         else

         {

                   return;

         }

同时服务器端和客户端都使用了自定义的windows消息WM_CLIENT_MSG,处理线程发送到主窗体的数据。