📄 sslserversocket.cpp
字号:
SOCKADDR_IN client;
int iAddrSize=sizeof(client);
m_pSocket = new CSslServerSocket();//用于连接
m_pSocket->m_pList=m_pList;
m_pSocket->m_pObSock=m_pObSock;//公用一个链表
m_pSocket->m_type=m_type;
m_pSocket->m_pConnection=m_pConnection;
if(Accept(*m_pSocket,(SOCKADDR *)&client,&iAddrSize))
{
CString str;
str.Format("客户 %s TCP接入成功,等待握手......",inet_ntoa(client.sin_addr));
m_pList->AddMsg(str,M_WARING);
m_pSocket->m_Ssl = SSL_new (m_Ctx);
SSL_set_accept_state(m_pSocket->m_Ssl);
sbio=BIO_new_socket(m_pSocket->m_hSocket,BIO_NOCLOSE);
SSL_set_bio(m_pSocket->m_Ssl,sbio,sbio);
for(;;)
{
if ((err = SSL_accept (m_pSocket->m_Ssl)) <= 0)
{
if (BIO_sock_should_retry(err))
{
continue;
}
int verify_error=SSL_get_verify_result(m_pSocket->m_Ssl);
if (verify_error != X509_V_OK)//succeeded or no peer certificate was presented
{
sprintf(out,"verify error:%s\n",
X509_verify_cert_error_string(verify_error));
m_pList->AddMsg(out,M_ERROR);
}
else
{
m_pList->AddMsg("客户端没有证书,握手结束",M_WARING);
m_pSocket->Close();
delete m_pSocket;
m_pSocket=NULL;
}
return ;
}
else
{
m_pSocket->AsyncSelect(FD_READ|FD_CLOSE);//选择读事件(OnReceive)
str.Format("握手结束,客户%s接入成功",inet_ntoa(client.sin_addr));
GetPeerInfo(m_pSocket->m_Ssl,&m_CLIENTINFO);
m_pList->AddMsg(str,M_WARING);
m_pObSock->AddTail(m_pSocket);
break;
}
}
}
else
{
m_pList->AddMsg("TCP连接失败",M_ERROR);
m_pSocket->Close();
delete m_pSocket;
m_pSocket=NULL;
}
CAsyncSocket::OnAccept(nErrorCode);
}
void CSslServerSocket::OnClose(int nErrorCode)
{
// TODO: Add your specialized code here and/or call the base class
CString clientIp;
unsigned int port;
POSITION pos;
GetPeerName(clientIp,port);//得到用户ip,port
clientIp+="已经断开连接!";
clientIp="客户"+clientIp;
m_pList->AddMsg(clientIp,M_WARING);
pos=m_pObSock->Find(this);
if(pos) m_pObSock->RemoveAt(pos);//客户端关闭
if(m_Ssl!=NULL)
{
SSlShouDown();
}
delete this;
CAsyncSocket::OnClose(nErrorCode);
}
int CSslServerSocket::SSlSend(char *buf, int len)
{
if(m_Ssl==NULL)
return -1;
int k=0;//接收数量
int offect=0;//偏移
for(;0!=len;)//maximum record size of 16kB for SSLv3/TLSv1
{
k = SSL_write(m_Ssl,buf+offect,len);
if (k <= 0)
{
if (BIO_sock_should_retry(k))
{
Sleep(100);
continue;//重试
}
return k;//出错
}
offect+=k;
len-=k;
}
AsyncSelect(FD_READ|FD_CLOSE);
return offect;
}
int CSslServerSocket::SSlReceive(char *buf, int len)
{
int k=0;
do
{
for(;;)
{
k = SSL_read(m_Ssl,buf,len);
if (k <= 0)
{
if (BIO_sock_should_retry(k))
{
Sleep(100);
continue;//重试
}
return k;//错误退出
}
break;//成功
}
}while (SSL_pending(m_Ssl));
return k;
}
void CSslServerSocket::DisplayError(_com_error &e)
{
CString msgText;
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
msgText.Format("连接数据库错误\n错误代码 = %08lx\n", e.Error());
msgText += " Msg: ";
msgText += e.ErrorMessage();
msgText += "\n 来源: ";
msgText += bstrSource;
msgText += "\n 内容: ";
msgText += bstrDescription;
m_pList->AddMsg(msgText,M_ERROR);
}
void CSslServerSocket::OnReceive(int nErrorCode) //与客户端交互
{
// TODO: Add your specialized code here and/or call the base class
if(m_type==0)//www
{
char buf[1024]={0};
SSlReceive(buf,1024);
AsyncSelect(FD_WRITE|FD_CLOSE);
}
else//ra
{
stuCA CA;//接收用结构
if(SSlReceive((char *)&CA,sizeof(stuCA))<=0)//对方已经关闭
return;
stuRA RA;//用于发送的结构
_variant_t Affected;//影响行数
_RecordsetPtr m_pRecordset;
m_pRecordset.CreateInstance(_uuidof(Recordset));
switch(CA.Type)
{
case Input://录入证书
{
stuCERT sCERT;
CString strSQL;
if(SSlReceive((char * )&sCERT,sizeof(sCERT))<0)//接收客户信息
return;
char * p=(char *)&sCERT;
VARIANT varBLOB;
SAFEARRAY FAR *psa;
SAFEARRAYBOUND rgsabound[1];
SYSTEMTIME tm;
GetLocalTime(&tm);
CString time;
time.Format("%d-%d-%d", tm.wYear,tm.wMonth,tm.wDay);
try
{
if (m_pConnection == NULL)
{
return;
}
m_pRecordset->Open("CERTLIST",_variant_t((IDispatch*)m_pConnection,true),
adOpenDynamic,adLockOptimistic,adCmdTable);//打开表
m_pRecordset->AddNew(); ///添加新记录
rgsabound[0].lLbound = 0;
rgsabound[0].cElements = sizeof(stuCERT);
psa = SafeArrayCreate(VT_UI1, 1, rgsabound); ///创建SAFEARRAY对象
for (long i =0;i<sizeof(stuCERT); i++)
{
SafeArrayPutElement (psa, &i, p++); ///保存二进制数据
}
// 由于Variant没有SafeArray的构造函数,所以手工设置Variant的数据类型和值。
varBLOB.vt = VT_ARRAY | VT_UI1;
varBLOB.parray = psa;
m_pRecordset->Fields->GetItem("USERINFO")->AppendChunk(varBLOB); ///加入数据
SafeArrayDestroy(psa);
m_pRecordset->Fields->GetItem("INPUTTIME")->PutValue(_variant_t(time));
_variant_t UserID=m_pRecordset->Fields->GetItem("ID")->Value;//得到id
m_pRecordset->Update(); //更新
RA.ID=UserID.lVal;//ID
RA.Type=Input;//操作类型
RA.State=TRUE;//操作状态
SSlSend((char *)&RA,sizeof(RA));
}
catch (_com_error &e)
{
DisplayError(e);
RA.Type=Input;//操作类型
RA.State=FALSE;//操作状态
SSlSend((char *)&RA,sizeof(RA));
}
break;
}
case FInputD://待审核
case FAuditD://待制作
case FMadeD://有效
case FRevokeD://无效
{
try
{
if (m_pConnection == NULL)
{
return;
}
m_pRecordset->Open((_bstr_t)CA.SQL,(IDispatch*)m_pConnection,adOpenStatic,//静态游标
adLockOptimistic,adCmdText);
m_Rcount=m_pRecordset->RecordCount;//纪录条数--静态游标有效
if(!m_pRecordset->adoEOF)//存在纪录
{
for(int index=0;!m_pRecordset->adoEOF;m_pRecordset->MoveNext(),index++)//遍历所有记录
{
//得到用户ID,个体信息
_variant_t varBLOB;
varBLOB = m_pRecordset->Fields->GetItem("USERINFO")->GetChunk(sizeof(RA.SUBJECT));
if(varBLOB.vt == (VT_ARRAY | VT_UI1))
{
char *pBuf = NULL;
SafeArrayAccessData(varBLOB.parray,(void **)&pBuf);
memcpy(&RA.SUBJECT,pBuf,sizeof(RA.SUBJECT));//个体信息
SafeArrayUnaccessData(varBLOB.parray);
}
_variant_t UserID=m_pRecordset->Fields->GetItem("ID")->Value;
RA.ID=UserID.lVal;//ID
switch(CA.Type)
{
case FInputD://查询代审核
{
_bstr_t InputTime=m_pRecordset->Fields->GetItem("INPUTTIME")->Value;
CString Input=InputTime.copy();
strcpy(RA.Time,Input);//操作时间
RA.Type=FInputD;//操作类型
RA.State=TRUE;//操作状态
if(index==0)//第一次发送总纪录数
{
RA.CertL=m_Rcount;//总纪录数
RA.KeyL=1;//KeyL=1 -->总纪录数
}
if(index==m_Rcount-1)//最后一条纪录(一条纪录时候m_Rcount=1)
{
RA.CertL=m_Rcount;//总纪录数
RA.KeyL=-1;
}
if(index!=0&&index!=m_Rcount-1)
{
RA.CertL=index;//其余发送纪录数
RA.KeyL=0;
}
break;
}
case FAuditD://查询代制作
{
_bstr_t AuditTime=m_pRecordset->Fields->GetItem("AUDITIME")->Value;
CString Audit=AuditTime.copy();
strcpy(RA.Time,Audit);//操作时间
RA.Type=FAuditD;//操作类型
RA.State=TRUE;//操作状态
if(index==0)//第一次发送总纪录数
{
RA.CertL=m_Rcount;//总纪录数
RA.KeyL=1;//KeyL=1 -->总纪录数
}
if(index==m_Rcount-1)//最后一条纪录(一条纪录时候m_Rcount=1)
{
RA.CertL=m_Rcount;//总纪录数
RA.KeyL=-1;
}
if(index!=0&&index!=m_Rcount-1)
{
RA.CertL=index;//其余发送纪录数
RA.KeyL=0;
}
break;
}
case FMadeD://查询已经制作
{
_bstr_t MadeTime=m_pRecordset->Fields->GetItem("MADETIME")->Value;
CString Made=MadeTime.copy();
strcpy(RA.Time,Made);//操作时间
RA.Type=FMadeD;//操作类型
RA.State=TRUE;//操作状态
if(index==0)//第一次发送总纪录数
{
RA.CertL=m_Rcount;//总纪录数
RA.KeyL=1;//KeyL=1 -->总纪录数
}
if(index==m_Rcount-1)//最后一条纪录(一条纪录时候m_Rcount=1)
{
RA.CertL=m_Rcount;//总纪录数
RA.KeyL=-1;
}
if(index!=0&&index!=m_Rcount-1)
{
RA.CertL=index;//其余发送纪录数
RA.KeyL=0;
}
break;
}
case FRevokeD: //查询已经作废
{
_bstr_t DelTime=m_pRecordset->Fields->GetItem("REVOKETIME")->Value;
CString Del=DelTime.copy();
strcpy(RA.Time,Del);//操作时间
RA.Type=FRevokeD;//操作类型
RA.State=TRUE;//操作状态
if(index==0)//第一次发送总纪录数
{
RA.CertL=m_Rcount;//总纪录数
RA.KeyL=1;//KeyL=1 -->总纪录数
}
if(index==m_Rcount-1)//最后一条纪录(一条纪录时候m_Rcount=1)
{
RA.CertL=m_Rcount;//总纪录数
RA.KeyL=-1;
}
if(index!=0&&index!=m_Rcount-1)
{
RA.CertL=index;//其余发送纪录数
RA.KeyL=0;
}
break;
}
default:
{
m_pList->AddMsg("未知命令",M_ERROR);
break;
}
}
if(SSlSend((char *)&RA,sizeof(RA))<=0)//发送
break;
}
}
else//纪录为0
{
switch(CA.Type)
{
case FInputD://查询代审核
{
RA.Type=FInputD;//操作类型
RA.State=TRUE;//操作状态
RA.KeyL=1;
break;
}
case FAuditD://查询代制作
{
RA.Type=FAuditD;//操作类型
RA.State=TRUE;//操作状态
RA.KeyL=1;
break;
}
case FMadeD://查询已经制作
{
RA.Type=FMadeD;//操作类型
RA.State=TRUE;//操作状态
RA.KeyL=1;
break;
}
case FRevokeD://查询已经作废
{
RA.Type=FRevokeD;//操作类型
RA.State=TRUE;//操作状态
RA.KeyL=1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -