1. 程式人生 > >C++傳智筆記(6):socket客戶端發送報文接受報文的api接口

C++傳智筆記(6):socket客戶端發送報文接受報文的api接口

內存泄露 rcp 分配內存 strcpy light cpp tac 第三方 _file__

#define  _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "itcast_comm.h"
#include "memwatch.h"
#include "itcastlog.h"

/*
下面定義了一套socket客戶端發送報文接受報文的api接口
請寫出這套接口api的調用方法
*/

/*
1 先把基本框架實現 版本管理
2 內存泄露檢查
3 日誌
4 版本優化
*/
//開發底層庫(開發接口),提供的是一種機制 ,而不是某種具體的策略。

//動態庫變成框架 
//1 第三方業務入口傳進來
//2 加密 解密 業務模型抽象
//實現 動態庫 加密解密業務模型抽象
typedef int (*EncData)(unsigned char *inData,int inDataLen,unsigned char *outData,int *outDataLen,void *Ref, int RefLen);
typedef int (*DecData)(unsigned char *inData,int inDataLen,unsigned char *outData,int *outDataLen,void *Ref, int RefLen);


typedef struct _SCK_HANDLE
{ char version[16]; char serverip[16]; int serverport; unsigned char * buf ; int buflen; EncData myEncDataFunc; void *EncRef; int EncRefLen; DecData myDecDataFunc; void *DecRef; int DecRefLen; }SCK_HANDLE; //抽象類型是_sck_handle,對象實例是sck_handle //客戶端初始化 ITCAST_FUNC_EXPORT(int) cltSocketInit(void **handle) //5day after { SCK_HANDLE
  *sh = NULL; int    rv = 0; ITCAST_LOG(__FILE__, __LINE__,LogLevel[1], rv,"func cltSocketInit() Begin"); if (handle == NULL) { rv = -1; ITCAST_LOG(__FILE__, __LINE__,LogLevel[4], rv,"func cltSocketInit(): check handle == NULL [%d]", rv); return rv; } //分配內存並初始化 sh = (SCK_HANDLE *)malloc(sizeof(SCK_HANDLE));
if (sh == NULL) { rv = -2; ITCAST_LOG(__FILE__, __LINE__,LogLevel[4], rv,"func cltSocketInit(): malloc err [%d]", rv); return rv; } memset(sh, 0, sizeof(SCK_HANDLE)); //域賦值 strcpy(sh->version, "0.0.1"); strcpy(sh->serverip, "192.168.0.211"); sh->serverport = 8888; //傳出 *handle = sh; ITCAST_LOG(__FILE__, __LINE__,LogLevel[1], rv,"func cltSocketInit() End"); return rv; } //客戶端發報文 ITCAST_FUNC_EXPORT(int) cltSocketSend(void *handle, unsigned char *buf, int buflen) { int rv = 0; SCK_HANDLE *sh = NULL; if (handle == NULL) { rv = -4; ITCAST_LOG(__FILE__, __LINE__,LogLevel[4], rv,"func cltSocketSend(): check handle == NULL [%d]", rv); return rv; } if (buf == NULL || buflen<=0) { rv = -5; ITCAST_LOG(__FILE__, __LINE__,LogLevel[4], rv,"func cltSocketSend(): (buf == NULL || len<=0) [%d]", rv); return rv; } sh = (SCK_HANDLE *)handle; sh->buf = (unsigned char *)malloc(sizeof(char)*buflen + 128); if (sh->buf == NULL) { rv = -6; ITCAST_LOG(__FILE__, __LINE__,LogLevel[4], rv,"func cltSocketSend() buflen:%d)", buflen); ITCAST_LOG(__FILE__, __LINE__,LogLevel[4], rv,"func cltSocketSend() check (handle->buf == NULL)) [%d]", rv); return rv; } if (sh->myEncDataFunc != NULL) { //回到 調用第三方廠商的加密業務 rv = sh->myEncDataFunc(buf, buflen, sh->buf, &sh->buflen, sh->EncRef, sh->EncRefLen); if (rv != 0) { ITCAST_LOG(__FILE__, __LINE__,LogLevel[4], rv,"sh->myEncDataFunc(buf, buflen, sh->buf, &sh->buflen):%d)", buflen); return rv; } } else { //把發送的報文數據,存儲 handle 上下文之中 memcpy(sh->buf, buf, buflen); sh->buflen = buflen; } return rv; } //回調函數的第二種寫法 //客戶端發報文 ITCAST_FUNC_EXPORT(int) cltSocketSend_enc(void *handle, unsigned char *buf, int buflen, EncData encDataCallbakFunc, void *ref, int refLen) { int rv = 0; SCK_HANDLE *sh = NULL; if (handle == NULL) { rv = -4; ITCAST_LOG(__FILE__, __LINE__,LogLevel[4], rv,"func cltSocketSend(): check handle == NULL [%d]", rv); return rv; } if (buf == NULL || buflen<=0) { rv = -5; ITCAST_LOG(__FILE__, __LINE__,LogLevel[4], rv,"func cltSocketSend(): (buf == NULL || len<=0) [%d]", rv); return rv; } sh = (SCK_HANDLE *)handle; sh->buf = (unsigned char *)malloc(sizeof(char)*buflen + 128); if (sh->buf == NULL) { rv = -6; ITCAST_LOG(__FILE__, __LINE__,LogLevel[4], rv,"func cltSocketSend() buflen:%d)", buflen); ITCAST_LOG(__FILE__, __LINE__,LogLevel[4], rv,"func cltSocketSend() check (handle->buf == NULL)) [%d]", rv); return rv; } if (encDataCallbakFunc != NULL) { //回到 調用第三方廠商的加密業務 rv = encDataCallbakFunc(buf, buflen, sh->buf, &sh->buflen, ref, refLen); if (rv != 0) { ITCAST_LOG(__FILE__, __LINE__,LogLevel[4], rv,"encDataCallbak(buf, buflen, sh->buf, &sh->buflen):%d)", buflen); return rv; } } else { //把發送的報文數據,存儲 handle 上下文之中 memcpy(sh->buf, buf, buflen); sh->buflen = buflen; } return rv; } //客戶端收報文 ITCAST_FUNC_EXPORT(int) cltSocketRev(void *handle, unsigned char *buf, int *buflen) { int rv = 0; SCK_HANDLE *sh = NULL; if (handle == NULL) { rv = -4; ITCAST_LOG(__FILE__, __LINE__,LogLevel[4], rv,"func cltSocketRev: check handle == NULL [%d]", rv); return rv; } if (buflen == NULL) { rv = -5; ITCAST_LOG(__FILE__, __LINE__,LogLevel[4], rv,"func cltSocketRev: (buflen == NULL) [%d]", rv); return rv; } sh = (SCK_HANDLE *)handle; //賦值 把上下文中的數據,copy到buf空間中 //支持二次調用,第一次調用求長度 第二次調用可以把數據copy buf中 if (buf != NULL) { memcpy(buf, sh->buf, sh->buflen); //buf[ci->buflen] = ‘\0‘; } *buflen = sh->buflen; return rv; } //客戶端釋放資源 ITCAST_FUNC_EXPORT(int) cltSocketDestory(void *handle) { SCK_HANDLE *sh = NULL; sh = handle; if (sh != NULL) { free(sh->buf); if (sh->EncRef != NULL) { free(sh->EncRef); } if (sh->DecRef != NULL) { free(sh->DecRef); } free(sh); } return 0; } /////////////////第二套api實現///////////////////////////////////////////////// //客戶端初始化 ITCAST_FUNC_EXPORT(int) cltSocketInit2(void **handle) //5day after { SCK_HANDLE *sh = NULL; int rv = 0; ITCAST_LOG(__FILE__, __LINE__,LogLevel[1], rv,"func cltSocketInit2() Begin"); if (handle == NULL) { rv = -1; ITCAST_LOG(__FILE__, __LINE__,LogLevel[4], rv,"func cltSocketInit2(): check handle == NULL [%d]", rv); return rv; } //分配內存並初始化 sh = (SCK_HANDLE *)malloc(sizeof(SCK_HANDLE)); if (sh == NULL) { rv = -2; ITCAST_LOG(__FILE__, __LINE__,LogLevel[4], rv,"func cltSocketInit2(): malloc err [%d]", rv); return rv; } memset(sh, 0, sizeof(SCK_HANDLE)); //域賦值 strcpy(sh->version, "0.0.1"); strcpy(sh->serverip, "192.168.0.211"); sh->serverport = 8888; //傳出 *handle = sh; ITCAST_LOG(__FILE__, __LINE__,LogLevel[1], rv,"func cltSocketInit2() End"); return rv; } //客戶端發報文 ITCAST_FUNC_EXPORT(int) cltSocketSend2(void *handle, unsigned char *buf, int buflen) { int rv = 0; SCK_HANDLE *sh = NULL; if (handle == NULL) { rv = -4; ITCAST_LOG(__FILE__, __LINE__,LogLevel[4], rv,"func cltSocketSend2(): check handle == NULL [%d]", rv); return rv; } if (buf == NULL || buflen<=0) { rv = -5; ITCAST_LOG(__FILE__, __LINE__,LogLevel[4], rv,"func cltSocketSend2(): (buf == NULL || len<=0) [%d]", rv); return rv; } sh = (SCK_HANDLE *)handle; sh->buf = (unsigned char *)malloc(sizeof(char)*buflen); if (sh->buf == NULL) { rv = -6; ITCAST_LOG(__FILE__, __LINE__,LogLevel[4], rv,"func cltSocketSend2() buflen:%d)", buflen); ITCAST_LOG(__FILE__, __LINE__,LogLevel[4], rv,"func cltSocketSend2() check (handle->buf == NULL)) [%d]", rv); return rv; } //把發送的報文數據,存儲 handle 上下文之中 memcpy(sh->buf, buf, buflen); sh->buflen = buflen; return rv; } //客戶端收報文 ITCAST_FUNC_EXPORT(int) cltSocketRev2(void *handle, unsigned char **buf, int *buflen) { int rv = 0; SCK_HANDLE *sh = NULL; if (handle == NULL) { rv = -4; ITCAST_LOG(__FILE__, __LINE__,LogLevel[4], rv,"func cltSocketRev2: check handle == NULL [%d]", rv); return rv; } if (buflen == NULL) { rv = -5; ITCAST_LOG(__FILE__, __LINE__,LogLevel[4], rv,"func cltSocketRev2: (buflen == NULL) [%d]", rv); return rv; } sh = (SCK_HANDLE *)handle; //分配內存數據傳出 *buf = (char *)malloc(sh->buflen); if (*buf == NULL) { rv = -6; ITCAST_LOG(__FILE__, __LINE__,LogLevel[4], rv,"func cltSocketRev2: (buflen == NULL) [%d]", rv); return rv; } memcpy(*buf, sh->buf, sh->buflen); *buflen = sh->buflen; return rv; } ITCAST_FUNC_EXPORT(int) cltSocketRev2_Free(unsigned char **buf) { int rv = 0; unsigned char * tmp = *buf; if (buf == NULL) { rv = -7; ITCAST_LOG(__FILE__, __LINE__,LogLevel[4], rv,"func cltSocketRev2: (buflen == NULL) [%d]", rv); return rv; } if (tmp != NULL) { free(tmp); } *buf = NULL; } //客戶端釋放資源 ITCAST_FUNC_EXPORT(int) cltSocketDestory2(void **handle) { SCK_HANDLE *sh = NULL; sh = *handle; if (sh != NULL) { free(sh->buf); free(sh); } *handle = NULL; return 0; } //實現了 把上層應用加密接口入口地址 賽入到動態庫 裏面 __declspec(dllexport) int clitSocket_SetEncFunc(void *handle, EncData encDataCallbak, void *ref, int refLen) { SCK_HANDLE *sh = NULL; sh = handle; if (handle == NULL) { return -1; } sh->myEncDataFunc = encDataCallbak; if (refLen > 0) { sh->EncRef = (void *)malloc(refLen); if (sh->EncRef == NULL) { return -2; } memcpy(sh->EncRef, ref, refLen); sh->EncRefLen = refLen; } return 0; } __declspec(dllexport) int clitSocket_SetDecFunc(void *handle, EncData decDataCallbak, void *ref, int refLen) { }

  

C++傳智筆記(6):socket客戶端發送報文接受報文的api接口