TCP通訊介面類,支援SSL通訊

來源:互聯網
上載者:User

 dd_tcp_connect.h

/* * dd_tcp_connect.h * *  Created on: 2011-7-13 *      Author: root */#ifndef DD_TCP_CONNECT_H_#define DD_TCP_CONNECT_H_#include <stdio.h>#include <string>#include <unistd.h>#include <errno.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <openssl/crypto.h>#include <openssl/x509.h>#include <openssl/pem.h>#include <openssl/ssl.h>#include <openssl/err.h>#include <pthread.h>class tcp_connect{public:tcp_connect();~tcp_connect();struct recvParam{SSL *ssl;int *sock;};//設定是否開啟SSL,預設是不開啟的void set_IsStartSSL(bool ssl);//設定認證和key所在的路徑,如果用於server端必須設定!bool set_CertAndKeyPath(char *certPath,char *keyPath);/*設定監聽IP和連接埠,如果是做server端,IP為NULL * 返回: * 0:成功* -1:bind失敗,檢查設定連接埠是否被佔用* -2:listen失敗.找找系統原因吧!* -3:soket申請失敗?? */intset_listen(unsigned short port,char *ip = NULL);/*初始化openssl的庫 * 返回:0 成功 * -1:newssl上下文失敗,檢查庫檔案 * -2 : 設定認證檔案失敗,檢查憑證路徑是否正確 * -3 : 設定私密金鑰檔案失敗,檢查死鑰路徑是否正確 * -4 : 驗證認證於私密金鑰不匹配,檢查兩者的正確性*/int init_SSL();//如果RP為空白則是作為用戶端應用int dd_Send(char *buf,int len,struct recvParam *rp = NULL);//如果RP為空白則是作為用戶端應用int dd_Recv(char *buf,int len,struct recvParam *rp = NULL);void set_disposal(void (*disposal)(char *recvbuf,int *len,tcp_connect *me,struct recvParam *rp));//如果是用作服務端啟動,之前必須設定處理回呼函數bool server_Run();//用戶端串連方法bool dd_Connect();void dd_Close();private:int server_st;bool isSSl;//是否開啟SSL通訊char *certPath;//認證所在路徑char *keyPath;//key私密金鑰所在路徑struct sockaddr_in sa_serv;struct sockaddr_in sa_cli;SSL_CTX *ctx;SSL_METHOD *meth;SSL *ssl;int *client_st;void (*disposal)(char *recvbuf,int *len,tcp_connect *me,struct recvParam *rp);static void *thread_recv(void *lp);};#endif /* DD_TCP_CONNECT_H_ */

 

dd_tcp_connect.cpp

/* * dd_tcp_connect.cpp * *  Created on: 2011-7-13 *      Author: root */#include "dd_tcp_connect.h"static tcp_connect *tt;tcp_connect::tcp_connect(){this->isSSl = false;//預設不開啟this->certPath = NULL;this->keyPath  = NULL;tt = this;}tcp_connect::~tcp_connect(){SSL_CTX_free (ctx);}void tcp_connect::set_IsStartSSL(bool ssl){this->isSSl = ssl;}bool tcp_connect::set_CertAndKeyPath(char *certPath,char *keyPath){if(certPath == NULL || keyPath == NULL || this->isSSl == false)return false;this->certPath = certPath;this->keyPath  = keyPath;return true;}int tcp_connect::init_SSL(){if(!isSSl)return -5;SSL_library_init();if(this->keyPath == NULL || this->certPath == NULL){meth = SSLv2_client_method();}elsemeth = SSLv23_server_method();ctx = SSL_CTX_new(meth);if(!ctx){return -1;}if(this->keyPath != NULL || this->certPath != NULL){  if(SSL_CTX_use_certificate_file(ctx,this->certPath,SSL_FILETYPE_PEM) <= 0)  {  return -2;  }  if(SSL_CTX_use_PrivateKey_file(ctx,this->keyPath,SSL_FILETYPE_PEM) <= 0)     {    return -3;     }  if(!SSL_CTX_check_private_key(ctx))     { return -4;     }}return 0;}int tcp_connect::set_listen(unsigned short port,char *ip){  server_st = socket(AF_INET,SOCK_STREAM,0);  if(server_st == -1) {return -3; }memset(&sa_serv,0,sizeof(sa_serv));sa_serv.sin_family      = AF_INET;if(ip == NULL)sa_serv.sin_addr.s_addr = INADDR_ANY;else{sa_serv.sin_addr.s_addr = inet_addr(ip);}sa_serv.sin_port        = htons (port);if(ip == NULL){if(bind(server_st,(struct sockaddr*)&sa_serv,sizeof (sa_serv)) == -1){  return -1;}if(listen(server_st,5) == 1){return -2;}}return 0;}bool tcp_connect::server_Run(){size_t client_len;client_len = sizeof(sa_cli);pthread_t tid;recvParam *rp;while(1){ client_st = new int();*client_st = accept(server_st,(struct sockaddr*) &sa_cli,&client_len);if(*client_st == -1){continue;}rp = new recvParam();if(isSSl){tt->ssl = SSL_new (ctx);SSL_set_fd (ssl,*client_st);SSL_accept (ssl);rp->sock = client_st;rp->ssl = ssl;} else      {rp->sock = client_st;rp->ssl = NULL;      }if(pthread_create(&tid,NULL,thread_recv,(void *)rp) != 0){close(*client_st);delete client_st;}client_st = NULL;ssl = NULL;}}void tcp_connect::set_disposal(void (*disposal)(char *recvbuf,int *len,tcp_connect *me,struct recvParam *rp)){this->disposal = disposal;}void *tcp_connect::thread_recv(void *lp){int len = 0;char *recvbuf = new char[65536];if(tt->isSSl){SSL *ssl = ((recvParam *)(lp))->ssl;while(1){len = SSL_read(ssl,recvbuf,65536);if(len <= 0){SSL_free (ssl);close(*((recvParam *)(lp))->sock);delete ((recvParam *)(lp))->sock;return NULL;}tt->disposal(recvbuf,&len,tt,((recvParam *)(lp)));}}else{int *sock = ((recvParam *)(lp))->sock;while(1){len = recv(*sock,recvbuf,65536,0);if(len == -1 || len == 0){close(*sock);delete sock;return NULL;}tt->disposal(recvbuf,&len,tt,((recvParam *)(lp)));}}return NULL;}int tcp_connect::dd_Send(char *buf,int len,struct recvParam *rp){int nlen;if(rp != NULL){if(isSSl){nlen = SSL_write(rp->ssl,buf,len);}else{nlen = send(*rp->sock,buf,len,0);}}else{if(isSSl){nlen = SSL_write(ssl,buf,len);}elsenlen = send(server_st,buf,len,0);}return nlen;}int tcp_connect::dd_Recv(char *buf,int len,struct recvParam *rp){int nlen;if(rp != NULL){if(isSSl){nlen = SSL_read(rp->ssl,buf,len);}else{nlen = recv(*rp->sock,buf,len,0);}}else{if(isSSl){nlen = SSL_read(ssl,buf,len);}elsenlen = recv(server_st,buf,len,0);}return  nlen;}bool tcp_connect::dd_Connect(){if(connect(server_st,(struct sockaddr*)&sa_serv,sizeof(sa_serv)) == -1){return false;}if(isSSl){ssl = SSL_new(ctx);SSL_set_fd(ssl,server_st);SSL_connect(ssl);//printf ("SSL connection using %s\n", SSL_get_cipher (ssl));}return true;}void tcp_connect::dd_Close(){close(server_st);SSL_free (ssl);SSL_CTX_free (ctx);}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.