рдпрд╣ рд▓реЗрдЦ рдореЗрд░реЗ рдкрд┐рдЫрд▓реЗ рд╡рд╛рд▓реЗ рдЬрд╛рд░реА рд░рдЦрддреЗ рд╣реИрдВ:
Ssl рд╕рдорд░реНрдерди рдХреЗ рд╕рд╛рде рд╕рдмрд╕реЗ рд╕рд░рд▓ рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рд╕рд░реНрд╡рд░рдЧреИрд░-рдЕрд╡рд░реБрджреНрдз рд╕реЙрдХреЗрдЯреНрд╕ рдХреЗ рд╕рд╛рде рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо https рд╕рд░реНрд╡рд░рдЧреИрд░-рдЕрд╡рд░реБрджреНрдз рд╕реЙрдХреЗрдЯреНрд╕ рдХреЗ рд╕рд╛рде рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо https рд╕рд░реНрд╡рд░ред рднрд╛рдЧ реирдЧреИрд░-рдЕрд╡рд░реБрджреНрдз рд╕реЙрдХреЗрдЯреНрд╕ рдХреЗ рд╕рд╛рде рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо https рд╕рд░реНрд╡рд░ред рднрд╛рдЧ рейрдореЗрд░реЗ рд▓реЗрдЦреЛрдВ рдореЗрдВ, рдореИрдВ рдЪрд░рдг-рджрд░-рдЪрд░рдг рдЧреИрд░-рдЕрд╡рд░реБрджреНрдз рд╕реЙрдХреЗрдЯреНрд╕ рдкрд░ рдПрдХрд▓-рдереНрд░реЗрдбреЗрдб рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рд╕рд░реНрд╡рд░ рдмрдирд╛рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реВрдВред
рдкрд┐рдЫрд▓реЗ рд╕рднреА рд▓реЗрдЦреЛрдВ рдореЗрдВ, рд╕рд░реНрд╡рд░ рдиреЗ рдХреЗрд╡рд▓ ssl рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдВрджреЗрд╢ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдП рдФрд░ рднреЗрдЬреЗред рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВ рд╕рд░реНрд╡рд░ рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рдЕрдирдПрдиреНрдХреНрд░рд┐рдкреНрдЯреЗрдб рдЯреАрд╕реАрдкреА рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рд╕рдорд░реНрдерди рдореЗрдВ рдЬреЛрдбрд╝рдиреЗ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реВрдВрдЧрд╛ рдФрд░ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЛ рдЧреНрд░рд╛рдлрд┐рдХ рдлрд╝рд╛рдЗрд▓ рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд░реНрд╡рд░ рдХреЛ рд╕рд┐рдЦрд╛рдКрдВрдЧрд╛ред
рд▓реЗрдХрд┐рди рдкрд╣рд▓реЗ, рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦреЛрдВ рдкрд░ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдереЛрдбрд╝рд╛ рдЪрд▓рдирд╛ред
1. рдореИрдВрдиреЗ std :: cout рдХреЗ рдкрдХреНрд╖ рдореЗрдВ рдкреНрд░рд┐рдВрдЯрдл рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдпреБрдХреНрддрд┐рдпрд╛рдВ рд╕реБрдиреАрдВред
2. рд╕реНрдорд╛рд░реНрдЯ рд▓реЛрдЧреЛрдВ рдиреЗ рдореБрдЭреЗ рд╕рд╛рдмрд┐рдд рдХрд┐рдпрд╛ рд╣реИ рдХрд┐ std :: memcpy рдФрд░ std :: рдХреЙрдкреА рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рд╣реИрдВред
рдореЗрдорд╕реАрдкреА рдореЗрд░реЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЬрд╛рд░реА рд░рдЦреВрдВрдЧрд╛ред
3.
рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рдХреА рд╕рднреА рд░рд┐рд▓реАрдЬрд╝реЛрдВ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рджрд┐рдпрд╛ рд╣реИ рдФрд░ рднрд╡рд┐рд╖реНрдп рдХреЗ рд▓реЛрдЧреЛрдВ рдХреЛ GitHub рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ , рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЙрдирдХреЗ рд▓рд┐рдП рд╡рд┐рдВрдбреЛрдЬ рдХреНрд▓рд╛рдЗрдВрдЯ, рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рднрдпрд╛рдирдХ рд╣реИред
4. рдХреМрди рдорд╛рдирддрд╛ рд╣реИ рдХрд┐ рд▓рд╛рдЗрдиреЗрдВ
const char on = 1; setsockopt(listen_sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) );
рд╕рд░реНрд╡рд░ рдХреЗ рдПрдХ рдЖрдкрд╛рддрдХрд╛рд▓реАрди рдкреБрдирд░рд╛рд░рдВрдн рдХреЗ рджреМрд░рд╛рди "рдкрддрд╛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЙрдкрдпреЛрдЧ рдореЗрдВ рддреНрд░реБрдЯрд┐" рд╕реЗ рдмрдЪрдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдВ - рд╡реЗ рдЧрдВрднреАрд░ рд░реВрдк рд╕реЗ рдЧрд▓рдд рд╣реИрдВред рд╡реЗ рдорджрдж рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗред
5. рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЬреЛ рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рд╡рд┐рднрд┐рдиреНрди рд╡рд░реНрдЧреЛрдВ рдХреЛ рд╣рдореЗрд╢рд╛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдлрд╝рд╛рдЗрд▓реЛрдВ рдореЗрдВ рд╡рд┐рддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдХреБрдЫ рддреЗрд▓ рдЬреЛрдбрд╝реЗрдВ: рдореИрдВ CClient рд╡рд░реНрдЧ рдХреЛ CServer рд╡рд░реНрдЧ рдХреЗ рдирд┐рдЬреА рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ!
рдпрд╣ рдерд╛:
CClient { *** }; CServer { *** };
рдпрд╣ рдмрди рдЧрдпрд╛:
CServer { CClient { *** }; *** };
рдЕрдм, рдпрджрд┐ рд╕рд░реНрд╡рд░ рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдмрди рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдХрд┐рд╕реА рдХреЛ рднреА CClient рд╡рд░реНрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рд╕реЛрдЪрдирд╛ рдЪрд╛рд╣рд┐рдП: рдпрд╣ рдПрдХ рдЙрдкрдпреЛрдЧрд┐рддрд╛ рд╡рд░реНрдЧ рд╣реИ рдЬрд┐рд╕реЗ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ CServer рд╡рд░реНрдЧ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
6. рдФрд░ рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдореБрдЦреНрдп () рдлрд╝рдВрдХреНрд╢рди рдПрд╕рдЖрдИ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рджреНрд╡рд╛рд░рд╛ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рдПрдХ рдирд╛рд╕реНрддрд┐рдХрддрд╛ рд╣реИред C ++ рдореЗрдВ, рдпрд╣ рд╢рд╛рдирджрд╛рд░ рд╣реИред рд▓реЗрдХрд┐рди рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдХрдВрдкрд╛рдЗрд▓рд░реЛрдВ рдХреЛ рдЕрднреА рддрдХ рдпрд╣ рдкрддрд╛ рдирд╣реАрдВ рд╣реИред
рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдЗрд╕ рдЕрдирд╛рд╡рд╢реНрдпрдХ рд╕рдорд╛рд░реЛрд╣ рдХреЛ "рджрдВрдбрд┐рдд" рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛, рдХреБрдЫ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╕реЗ рджреВрд░ рд▓реЗ рдЬрд╛рдХрд░ - рдореИрдВрдиреЗ рдлрд╝рд╛рдЗрд▓ рдХреЛ рдмрджрд▓ рджрд┐рдпрд╛ред
#include "server.h" const server::CServer s(8085, 1111); int main() {return 0;}
рдЕрдм рдореБрдЦреНрдп рдмрд╛рдд рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ ...
рд╕рдорд░реНрдерди рд╕рд░реНрд╡рд░ рдкрд░ рдЕрдирдПрдиреНрдХреНрд░рд┐рдкреНрдЯреЗрдб tcp рдХрдиреЗрдХреНрд╢рди рдЬреЛрдбрд╝рдирд╛
рд╕рд░реНрд╡рд░ рдореЗрдВ рдЕрдирдПрдиреНрдХреНрд░рд┐рдкреНрдЯреЗрдб рдФрд░ рдПрдиреНрдХреНрд░рд┐рдкреНрдЯреЗрдб рдХрдиреЗрдХреНрд╢рди рдЖрдорддреМрд░ рдкрд░ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдкреЛрд░реНрдЯ рдкрд░ рд╕реНрд╡реАрдХрд╛рд░ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдкрд╣рд▓реА рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рд╕рд░реНрд╡рд░ рдХреЗ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЛ рдмрджрд▓ рджреЗрдВ рдФрд░ рджреВрд╕рд░реЗ рд╕реБрдирдиреЗ рд╡рд╛рд▓реЗ рд╕реЙрдХреЗрдЯ рдХреЗ рд▓рд┐рдП рд╡реИрд░рд┐рдПрдмрд▓ рдЬреЛрдбрд╝реЗрдВред
рдХреЗ рдмрджрд▓реЗ
struct epoll_event m_ListenEvent;
рд╕рд░реНрд╡рд░ рд╡рд░реНрдЧ рдореЗрдВ рд▓рд┐рдЦреЗрдВ
struct epoll_event m_ListenEventTCP, m_ListenEventSSL;
рд╕рд░реНрд╡рд░ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдореЗрдВ, рд▓рд┐рдирдХреНрд╕ рдХреЗ рд▓рд┐рдП рдкреЛрд░реНрдЯ рдирдВрдмрд░ рдФрд░ рдХреЛрдб рдЬреЛрдбрд╝реЗрдВ, рдЬреЛ рдЯреАрд╕реАрдкреА рдкреЛрд░реНрдЯрд▓ рдореЗрдВ рддреНрд░реБрдЯрд┐ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рд╕рд░реНрд╡рд░ рдХреЛ рдХреНрд░реИрд╢ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрдЧрд╛:
CServer(const int nPortTCP, const int nPortSSL) { #ifndef WIN32 struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = SIG_IGN; sigaction(SIGPIPE, &sa, NULL); #else WSADATA wsaData; if ( WSAStartup( MAKEWORD( 2, 2 ), &wsaData ) != 0 ) { cout << "Could not to find usable WinSock in WSAStartup\n"; return; } #endif
рд╣рдо рд╕реБрдирдиреЗ рдХреЗ рд╕реЙрдХреЗрдЯ рдЖрд░рдВрдн рдХрд░рдиреЗ рдФрд░ рдПрдХ рдирдП рдЧреНрд░рд╛рд╣рдХ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрд▓рдЧ-рдЕрд▓рдЧ рдХрд╛рд░реНрдп рд▓рд┐рдЦреЗрдВрдЧреЗ:
private: void InitListenSocket(const int nPort, struct epoll_event &eventListen) { SOCKET listen_sd = socket (AF_INET, SOCK_STREAM, 0); SET_NONBLOCK(listen_sd); const char on = 1; setsockopt(listen_sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) ); struct sockaddr_in sa_serv; 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 (nPort); int err = ::bind(listen_sd, (struct sockaddr*) &sa_serv, sizeof (sa_serv)); if (err == -1) { cout << "bind error = " << errno << "\n"; return; } err = listen (listen_sd, SOMAXCONN); eventListen.data.fd = listen_sd; eventListen.events = EPOLLIN | EPOLLET; epoll_ctl (m_epoll, EPOLL_CTL_ADD, listen_sd, &eventListen); } void AcceptClient(const SOCKET hSocketIn, const bool bIsSSL) { cout << "AcceptClient"; struct sockaddr_in sa_cli; size_t client_len = sizeof(sa_cli); #ifdef WIN32 const SOCKET sd = accept (hSocketIn, (struct sockaddr*) &sa_cli, (int *)&client_len); #else const SOCKET sd = accept (hSocketIn, (struct sockaddr*) &sa_cli, (socklen_t *)&client_len); #endif if (sd != INVALID_SOCKET) { cout << "Accepted\n"; // m_mapClients[sd] = shared_ptr<CClient>(new CClient(sd, bIsSSL)); auto it = m_mapClients.find(sd); if (it == m_mapClients.end()) return; // epoll struct epoll_event ev = it->second->GetEvent(); epoll_ctl (m_epoll, EPOLL_CTL_ADD, it->first, &ev); } }
рдЕрдм рдХреНрд▓рд╛рдЗрдВрдЯ рдореЗрдВ рд╣рдо рд╡реИрд░рд┐рдПрдмрд▓ m_bIsSSL рдХреЛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рдЬрд┐рд╕реЗ рд╣рдо рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдореЗрдВ рд╢реБрд░реВ рдХрд░реЗрдВрдЧреЗ, рдФрд░ рдлрд┐рд░ рдХреЙрд▓рдмреИрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдмрджрд▓реЗрдВрдЧреЗ рддрд╛рдХрд┐ рд╡реЗ рдЯреАрд╕реАрдкреА рдХрдиреЗрдХреНрд╢рди рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХреЗрдВ:
рдХреЗ рдмрджрд▓реЗ
const RETCODES AcceptSSL() { if (!m_pSSLContext)
рдЕрдм рдпрд╣ рд╣реЛрдЧрд╛:
const RETCODES AcceptSSL() { cout << "AcceptSSL\n"; if (!m_bIsSSL) return RET_READY; if (!m_pSSLContext) return RET_ERROR;
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдХрд╣реАрдВ рднреА рд╕рд░рд▓ рдирд╣реАрдВ рд╣реИ: рдЯреАрд╕реАрдкреА рд╕реНрд╡реАрдХрд╛рд░ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдФрд░ рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рднреА рдЕрддрд┐рд░рд┐рдХреНрдд рдЗрд╢рд╛рд░реЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
рдЯреАрд╕реАрдкреА рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдкреНрд░рдорд╛рдг рдкрддреНрд░ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╕рдВрдмрдВрдзрд┐рдд рдлрд╝рдВрдХреНрд╢рди рдХреА рд╢реБрд░реБрдЖрдд рдЕрдм рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрд╛рдИ рджреЗрдЧреА:
const RETCODES GetSertificate() { cout << "GetSertificate\n"; if (!m_bIsSSL) return RET_READY;
рдХрд┐рд╕реА рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдХреНрд▓рд╛рдЗрдВрдЯ рд╕реЗ рдбреЗрдЯрд╛ рдкрдврд╝рддрд╛ рд╣реИ, рдЗрд╕рдХреЗ рдмрдЬрд╛рдп ContinueRead () рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ
unsigned char szBuffer[4096]; const int err = SSL_read (m_pSSL, szBuffer, 4096);
рдХреЛрдб рд▓рд┐рдЦреЗрдВ:
static char szBuffer[4096];
рдЙрд╕реА рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ, рдЖрдкрдХреЛ рдЕрдм рдЯреАрд╕реАрдкреА рдХрдиреЗрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдХреЛрдб рдХреЛ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛ред рдПрд╕рдПрд╕рдПрд▓ рдХреЗ рд╕рд╛рде, рддреНрд░реБрдЯрд┐ рд╣реЛрдЧреА
рдпрджрд┐ рд╕рдВрджреЗрд╢ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдлрд╝рдВрдХреНрд╢рди рдирдХрд╛рд░рд╛рддреНрдордХ рдпрд╛ рд╢реВрдиреНрдп рдорд╛рди рд▓реМрдЯрд╛рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЪреВрдВрдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЧреИрд░-рдЕрд╡рд░реБрджреНрдз рд╕реЙрдХреЗрдЯ рд╣реИрдВ,
рддрдм рд╡рд┐рдВрдбреЛрдЬ рдкрд░ WSAEWOULDBLOCK рдФрд░ рд▓рд┐рдирдХреНрд╕ рдкрд░ EWOULDBLOCK рдХреА рддреНрд░реБрдЯрд┐ рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╕рдм рдХреБрдЫ рдареАрдХ рд╣реИ, рдмрд╕ рдЗрдВрддрдЬрд╛рд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред
рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдореИрдХреНрд░реЛ рдЬреЛрдбрд╝реЗрдВ:
#ifndef _WIN32 #define S_OK 0 #define WSAEWOULDBLOCK EWOULDBLOCK #define WSAGetLastError() errno #endif
рдФрд░ ContinueRead рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдРрд╕рд╛ рдХреЛрдб:
if (!m_bIsSSL) { if ((err == 0) || ((m_nLastSocketError != WSAEWOULDBLOCK) && (m_nLastSocketError != S_OK))) return RET_ERROR; } else { if ((err == 0) || ((m_nLastSocketError != SSL_ERROR_WANT_READ) && (m_nLastSocketError != SSL_ERROR_WANT_WRITE))) return RET_ERROR; }
рдФрд░ CClient :: GetLastError рдлрд╝рдВрдХреНрд╢рди рд╣рдо рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ
private: int GetLastError(int err) const { if (m_bIsSSL) return SSL_get_error(m_pSSL, err); else return WSAGetLastError(); }
рдареАрдХ рдЙрд╕реА рддрд░рд╣, рд╣рдо ContinueWrite рд╕рдВрджреЗрд╢ рднреЗрдЬрдиреЗ рд╡рд╛рд▓реЗ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдареАрдХ рдХрд░реЗрдВрдЧреЗ рдФрд░ рд╣рдорд╛рд░реЗ рдПрдХрд▓-рдереНрд░реЗрдбреЗрдб рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рд╕рд░реНрд╡рд░ рдЧреНрд░рд╛рд╣рдХреЛрдВ рд╕реЗ рдЕрдиреБрд░реЛрдз рд╣реЗрдбрд░ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдЯреАрд╕реАрдкреА рдФрд░ рдПрд╕рдПрд╕рдПрд▓ рдХрдиреЗрдХреНрд╢рди рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИрдВред
рдЖрдЗрдП рдЖрдЬ рд╣рдо рдЕрдкрдиреЗ рд╕рд░реНрд╡рд░ рдХреЛ рдпрд╣ рд╕рд┐рдЦрд╛рддреЗ рд╣реИрдВ рдХрд┐ рдХреНрд▓рд╛рдЗрдВрдЯреНрд╕ рдХреЛ рдлрд╛рдЗрд▓ рдХреИрд╕реЗ рджреЗрдВ
рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдЗрд╕ рддрдереНрдп рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рднреА рд╡рд┐рд╢реЗрд╖ рдирд╣реАрдВ рд╣реИ рдХрд┐ рд▓рд┐рдирдХреНрд╕ рдкрд░ рдЕрдиреНрдп рдкреНрд░рдгрд╛рд▓рд┐рдпреЛрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдлрд╝рд╛рдЗрд▓ рднреЗрдЬрдиреЗ рдХрд╛ рдПрдХ рддреЗрдЬрд╝ рддрд░реАрдХрд╛ рд╣реИ: рд╕реЗрдВрдбрдлрд╛рдЗрд▓ рдлрд╝рдВрдХреНрд╢рдиред
рдХреЛрдб рдХреЛ рд╕реБрд╕рдВрдЧрдд рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВ рд╕реБрдЭрд╛рд╡ рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рд╣рдо рднреЗрдЬрдиреЗ рдХреЗ рд╕рд╛рде рднреА рд╡реИрд╕рд╛ рд╣реА рдХрд░реЗрдВ рдЬреИрд╕рд╛ рдХрд┐ рд╣рдордиреЗ рдПрдкреЛрд▓ рдХреЗ рд╕рд╛рде рдХрд┐рдпрд╛ рдерд╛: рд▓рд┐рдирдХреНрд╕ рдХреЛ рдЫреЛрдбрд╝рдХрд░ рд╕рднреА рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд▓рд┐рдП рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдПрдХ рдПрдореБрд▓реЗрдЯрд░ рд▓рд┐рдЦреЗрдВред
Sendfile рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░реЗрдВ
1. рдЦрд╛рд▓реА рдлрд╛рдЗрд▓реЗрдВ "sendfile.h", "sendfile.cpp" рдмрдирд╛рдПрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд╡рд┐рдЬреБрдЕрд▓ рд╕реНрдЯреВрдбрд┐рдпреЛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдЬреЛрдбрд╝реЗрдВред
2. sendfile.h рдореЗрдВ рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдбрд╛рд▓рддреЗ рд╣реИрдВ:
#ifndef __linux__ #ifndef _SENDFILE_H #define _SENDFILE_H #include <sys/types.h> unsigned long long sendfile(int out_fd, int in_fd, off_t *offset, size_t count); #endif #endif
3. sendfile.cpp рдореЗрдВ, рдЗрд╕реЗ рдбрд╛рд▓реЗрдВ:
#include <io.h> #include <Winsock2.h> #pragma comment(lib, "ws2_32.lib") #endif unsigned long long sendfile(int out_fd, int in_fd, off_t *offset, size_t count) { static unsigned char buffer[4096]; if (count > 4096) count = 4096; off_t lPos = _lseek(in_fd, *offset, SEEK_SET); if (lPos == -1) return -1; const int nReaded = _read(in_fd, buffer, count); if (nReaded == 0) return nReaded; if (nReaded == -1) return -1; *offset += nReaded; errno = 0; const int nSended = send(out_fd, (const char *)buffer, nReaded, 0); if (nSended != SOCKET_ERROR) return nSended; if (WSAGetLastError() != WSAEWOULDBLOCK) return -1; return 0; } #endif
4. рд╕рд░реНрд╡рд░ рд╡рд░реНрдЧ рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рд╕рдорд╛рд╡реЗрд╢рди рдЬреЛрдбрд╝реЗрдВ рддрд╛рдХрд┐ рд▓рд┐рдирдХреНрд╕ рдореЗрдВ рдорд╛рдирдХ рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рд╣рдорд╛рд░рд╛ рдЙрдкрдпреЛрдЧ рдЕрдиреНрдп рдкреНрд░рдгрд╛рд▓рд┐рдпреЛрдВ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдорд╛рд╡реЗрд╢рди рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ рдФрд░ рдЙрд╕ рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдкрде рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рд╕реЗ рд╣рдо рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рднреЗрдЬреЗрдВрдЧреЗ:
#ifdef __linux__ #include <sys/epoll.h> #include <sys/sendfile.h> #define O_BINARY 0 #else #include "epoll.h" #include "sendfile.h" #endif #include <sys/stat.h> #define SEND_FILE "./wwwroot/festooningloops.jpg"
рдЕрдиреБрдХрд░рдг рднреЗрдЬрдиреЗ рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реЛ рдЧрдпрд╛ред
рдлрд╝рд╛рдЗрд▓ рднреЗрдЬреЗрдВ
5. рдЧреНрд░рд╛рд╣рдХ рд╡рд░реНрдЧ рдореЗрдВ рдПрдХ рдлрд╝рд╛рдЗрд▓ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдФрд░ рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдЬреЛрдбрд╝реЗрдВ
class CClient { int m_nSendFile; off_t m_nFilePos; unsigned long long m_nFileSize;
6. InitRead рдлрд╝рдВрдХреНрд╢рди рдмрджрд▓реЗрдВ ()
const RETCODES InitRead() { if (m_bIsSSL && (!m_pSSLContext || !m_pSSL)) return RET_ERROR; m_nSendFile = _open(SEND_FILE, O_RDONLY|O_BINARY); if (m_nSendFile == -1) return RET_ERROR; struct stat stat_buf; if (fstat(m_nSendFile, &stat_buf) == -1) return RET_ERROR; m_nFileSize = stat_buf.st_size;
7. tcp рдФрд░ ssl рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдлрд╝рд╛рдЗрд▓ рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдлрд╝рдВрдХреНрд╢рди рдЬреЛрдбрд╝реЗрдВ:
const RETCODES SendFileSSL(const int nFile, off_t *offset) { if (nFile == -1 || m_vSendBuffer.size()) return ContinueWrite(); if (!m_bIsSSL || !m_pSSLContext || !m_pSSL) return RET_ERROR; static unsigned char buffer[4096]; off_t lPos = _lseek(nFile, *offset, SEEK_SET); if (lPos == -1) return RET_ERROR; const int nReaded = _read(nFile, buffer, 4096); if (nReaded == -1) return RET_ERROR; if (nReaded > 0) { *offset += nReaded; m_vSendBuffer.resize(nReaded); memcpy(&m_vSendBuffer[0], buffer, nReaded); } return RET_WAIT; } const RETCODES SendFileTCP(const int nFile, off_t *offset) { if (nFile == -1 || m_vSendBuffer.size()) return ContinueWrite(); const unsigned long long nSended = sendfile(m_hSocket, nFile, offset, 4096); if (nSended == (unsigned long long)-1) return RET_ERROR; m_nLastSocketError = WSAEWOULDBLOCK; return RET_WAIT; } const bool IsAllWrited() const { if (m_nSendFile == -1 && m_vSendBuffer.size()) return true; if (m_nFileSize == (unsigned long long)m_nFilePos) return true; return false; }
8. рдЧреНрд░рд╛рд╣рдХ рдХреЗ рдХреЙрд▓рдмреИрдХ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рддрд░реНрдХ рдмрджрд▓реЗрдВ:
case S_WRITING: { if (!m_bIsSSL && (SendFileTCP(m_nSendFile, &m_nFilePos) == RET_ERROR)) return false; else if (m_bIsSSL && (SendFileSSL(m_nSendFile, &m_nFilePos) == RET_ERROR)) return false; if (IsAllWrited()) SetState(S_ALL_WRITED, pCurrentEvent); return true; }
рд╣рдорд╛рд░рд╛ рд╕рд░реНрд╡рд░ рддреИрдпрд╛рд░ рд╣реИ!
рдЕрдм рд╡рд╣ рди рдХреЗрд╡рд▓ рдмрдлрд░ рднреЗрдЬ рд╕рдХрддрд╛ рд╣реИ, рдмрд▓реНрдХрд┐ рдлрд╛рдЗрд▓реЗрдВ рднреА рднреЗрдЬ рд╕рдХрддрд╛ рд╣реИред рд╢рд╛рдпрдж рдХрд┐рд╕реА рдиреЗ рджреЗрдЦрд╛ рдХрд┐ рдХреНрд▓рд╛рдЗрдВрдЯ рд╡рд░реНрдЧ рдореЗрдВ "m_nLastSocketError" рдЪрд░ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рдерд╛ ...
рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рд╕рд░реНрд╡рд░ рдХреЗ рдкрд┐рдЫрд▓реЗ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдореЗрдВ рд╣рдордиреЗ рд╣рдореЗрд╢рд╛ рд╕реЙрдХреЗрдЯреНрд╕ рд╕реЗ рдХрд┐рд╕реА рднреА рдИрд╡реЗрдВрдЯ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХреА рдереА, рдЕрдм m_nLastSocketError рд╡реИрд░рд┐рдПрдмрд▓ рд╣рдореЗрдВ CClient :: SetState рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛ рддрд╛рдХрд┐ рдПрдкреЛрд▓ рдлрд╝рдВрдХреНрд╢рди
рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рдШрдЯрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЗрдВрддрдЬрд╛рд░ рдХрд░ рд░рд╣реЗ рд╕реЙрдХреЗрдЯреНрд╕ рд╕реЗред
void SetState(const STATES state, struct epoll_event *pCurrentEvent) { m_stateCurrent = state; pCurrentEvent->events = EPOLLERR | EPOLLHUP; if (m_bIsSSL) { if (m_nLastSocketError == SSL_ERROR_WANT_READ) pCurrentEvent->events |= EPOLLIN; if (m_nLastSocketError == SSL_ERROR_WANT_WRITE) pCurrentEvent->events |= EPOLLOUT; return; } if (m_nLastSocketError == WSAEWOULDBLOCK) { if (m_stateCurrent == S_READING) pCurrentEvent->events |= EPOLLIN; if (m_stateCurrent == S_WRITING) pCurrentEvent->events |= EPOLLOUT; return; } pCurrentEvent->events |= EPOLLIN | EPOLLOUT; }
рд╕рдм рдХреБрдЫ рддреИрдпрд╛рд░ рд╣реИ!
Visual Studio 2012 рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП , ssl_test.sln рдлрд╝рд╛рдЗрд▓ рдЦреЛрд▓реЗрдВ рдФрд░ рд╕рдВрдХрд▓рд┐рдд рдХрд░реЗрдВред
рд▓рд┐рдирдХреНрд╕ рдкрд░ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдлрд╝рд╛рдЗрд▓реЗрдВ epoll.h, epoll.cpp, sendfile.h рдФрд░ sendfile.cpp рдХреА
рдЬрд░реВрд░рдд рдирд╣реАрдВ рд╣реИ , рддрд╛рдХрд┐ рд╕рдм рдХреБрдЫ рдХрд╛рдо рдХрд░реЗ, рдмрд╕ рдлрд╛рдЗрд▓реЛрдВ рдХреЛ рдЙрд╕реА рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рдХреЙрдкреА рдХрд░реЗрдВ: serv.cpp, server.h, ca-cert.pem, wwwroot рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдмрдирд╛рдПрдВ рдФрд░ рд╡рд╣рд╛рдВ ./wwwroot/festooningloops.jpg рдлрд╝рд╛рдЗрд▓ рдХреА рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдмрдирд╛рдПрдБ, рдлрд┐рд░ рдХрдорд╛рдВрдб рдкреНрд░реЙрдореНрдкреНрдЯ рдкрд░ рдЯрд╛рдЗрдк рдХрд░реЗрдВ: "g ++ -std = c ++ 0x -L / usr / lib -lssl -lcrypto servpp" рдЬреЛ рдХрд┐рд╕реА рдХрд╛рд░рдг рд╕реЗ рд╕рдВрдХрд▓рдХ рдЪреЗрддрд╛рд╡рдиреА рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ, -Wall рдСрдкреНрд╢рди рдХреЛ рдЗрд╕рдореЗрдВ рдЬреЛрдбрд╝реЗрдВред
рдЖрдк рд╕рд░реНрд╡рд░ рдХреЛ рд╢реБрд░реВ рдХрд░рдиреЗ рдФрд░ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЗ рдПрдбреНрд░реЗрд╕ рдмрд╛рд░ рдореЗрдВ рдЯрд╛рдЗрдк рдХрд░рдХреЗ рд╕реНрдерд╛рдиреАрдп рдХрдВрдкреНрдпреВрдЯрд░ рдкрд░ рд╕рд░реНрд╡рд░ рдХреА рдЬрд╛рдВрдЪ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ
localhost:1111
рдпрд╛
localhost:8085