通常網路密碼驗證過程是這樣的:用戶端在獲取使用者輸入的用戶名和密碼資訊之後創建socket通訊端與遠端伺服器建立一個連接,發送用戶名和密碼並等待伺服器返回消息,伺服器收到用戶名和密碼之後查詢伺服器資料庫,如果用戶名密碼正確返回給用戶端一個登錄成功消息,否則返回一個密碼錯誤的消息! 
 
下面是用VC++實現驗證過程中的部分代碼,代碼有點亂: 
//獲取使用者輸入資訊 
void CClientDlg::OnOK() 

//之前socket已經經過初始化 
UpdateData(); 
if(m_username.IsEmpty()||m_userID.IsEmpty()) 
  MessageBox("請輸入所有資訊!","用戶登錄",MB_OK); 
else 

  if(Load()) //調用驗證函數 
  { 
//   close(destSocket); 
   closesocket(destSocket); 
   CDialog::OnOK(); 
   MessageBox("登陸成功!","用戶登錄",MB_OK);//驗證成功 
   CChat chat; 
   chat.m_username=m_username; 
//   chat.res=res; 
   chat.DoModal(); 
  } 
  else 
  {      //驗證失敗 
   MessageBox("尚未註冊或\n用戶名/密碼有誤。","用戶登錄",MB_OK); 
  } 


BOOL CClientDlg::Load() //發送"Load:" 

////////////////////////發送登陸資訊並接收回饋資訊///////////////////////////// 
char sendText[100],recvText[5025]; 
int numsnt,numrcv,status; 
sprintf(sendText,"Load:%s,%s",m_username,m_userID); 
numsnt=send(destSocket, sendText, strlen(sendText) + 1, NO_FLAGS_SET); 
if (numsnt != (int)strlen(sendText) + 1) 
    { 
  MessageBox("ERROR: Connection terminated!","用戶登錄",MB_OK); 
  status=closesocket(destSocket); 
  if (status == SOCKET_ERROR) 
   MessageBox("ERROR: closesocket unsuccessful!","用戶登錄",MB_OK); 
     status=WSACleanup(); 
  if (status == SOCKET_ERROR) 
   MessageBox("ERROR: WSACleanup unsuccessful!","用戶登錄",MB_OK); 
  return false; 
    } 
numrcv=recv(destSocket, recvText, 5025, NO_FLAGS_SET); 
if ((numrcv == 0) || (numrcv == SOCKET_ERROR)) 
    { 
      MessageBox("ERROR: Connection terminated!","用戶登錄",MB_OK); 
      status=closesocket(destSocket); 
      if (status == SOCKET_ERROR) 
    MessageBox("ERROR: closesocket unsuccessful!","用戶登錄",MB_OK); 
      status=WSACleanup(); 
      if (status == SOCKET_ERROR) 
    MessageBox("ERROR: WSACleanup unsuccessful!","用戶登錄",MB_OK); 
      return false; 
    } 
recvText[numrcv]='\0'; 
////////////////////////////////////////////////////////////////////////////// 
/////////////////////讀取返回標誌和使用者資訊/////////////////////////////////// 
char Flag[10]; 
char *pos=strchr(recvText,'!'); 
pos+=1; 
int len_text=strlen(recvText); 
int len_pos=strlen(pos); 
int len=len_text-len_pos; 
for(int i=0;i<len;i++) 
  Flag[i]=recvText[i]; 
Flag[len]='\0'; 
if(strcmp(Flag,"success!")!=0) 
  return false; 
/////////////////////////////////////////////////////////////////////////////// 
///////////////////////將使用者資訊寫入與用戶名對應的檔//////////////////////// 
else 

  CString filename; 
  filename.Format(".\\data\\%s.db",m_username); 
  FILE *file; 
  if((file=fopen(filename,"w"))!=NULL) 
  { 
   fprintf(file,"%s",pos); 
  } 
  fclose(file); 

/////////////////////////////////////////////////////////////////////////////// 
return true; 

//附網路初始化代碼 
BOOL CClientDlg::Init_net() 

/////////////////////////網路初始化/////////////////////////////////// 
status=WSAStartup(MAKEWORD(1, 1), &Data); 
if (status != 0) 
  MessageBox("ERROR: WSAStartup unsuccessful!","用戶登錄",MB_OK); 
destAddr=inet_addr(DEST_IP_ADDR);  //暫時定為本機使用 
memcpy(&destSockAddr.sin_addr, &destAddr,sizeof(destAddr)); 
destSockAddr.sin_port=htons(606); 
destSockAddr.sin_family=AF_INET; 
destSocket=socket(AF_INET, SOCK_STREAM, 0); 
if (destSocket == INVALID_SOCKET) 

  MessageBox("ERROR: socket unsuccessful!","用戶登錄",MB_OK); 
  status=WSACleanup(); 
  if (status == SOCKET_ERROR) 
   MessageBox("ERROR: WSACleanup unsuccessful!","用戶登錄",MB_OK); 
  return false; 

////////////////////////////////////////////////////////////////////// 
///////////////////////////連接網路//////////////////////////////////////////// 
status=connect(destSocket, (LPSOCKADDR) &destSockAddr,sizeof(destSockAddr)); 
if (status == SOCKET_ERROR) 

  MessageBox("ERROR: connect unsuccessful!","用戶登錄",MB_OK); 
  status=closesocket(destSocket); 
  if (status == SOCKET_ERROR) 
   MessageBox("ERROR: closesocket unsuccessful!","用戶登錄",MB_OK); 
  status=WSACleanup(); 
  if (status == SOCKET_ERROR) 
   MessageBox("ERROR: WSACleanup unsuccessful!","用戶登錄",MB_OK); 
  return false; 

/////////////////////////////////////////////////////////////////////////////// 
return true; 


//////////////////////////////////服務端代碼///////////////////////////////// 
//建立一個基於消息的非同步通訊端 
BOOL CSkyQQsrvDlg::InitSocket() 

m_socket=WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,0); //WSASocket創建通訊端 
if(INVALID_SOCKET==m_socket) 

  MessageBox("創建通訊端失敗!"); 
  return FALSE; 

SOCKADDR_IN addrSock; 
addrSock.sin_addr.S_un.S_addr=htonl(INADDR_ANY); 
addrSock.sin_family=AF_INET; 
addrSock.sin_port=htons(606);//設置606為監聽埠 
if(SOCKET_ERROR==bind(m_socket,(SOCKADDR*)&addrSock,sizeof(SOCKADDR))) 

  MessageBox("綁定失敗!"); 
  return FALSE; 

if(SOCKET_ERROR==WSAAsyncSelect(m_socket,m_hWnd,UM_SOCK,FD_READ))//請求一個基於消息的網路事件通知非同步通訊端 

  MessageBox("註冊網路讀取事件失敗!"); 
  return FALSE; 

return TRUE; 

//建立消息映射,在SkyQQsrvDlg.h中添加 
#define UM_SOCK  WM_USER+1 //定義消息 
//消息映射 
BEGIN_MESSAGE_MAP(CSkyQQsrvDlg, CDialog) 
//{{AFX_MSG_MAP(CSkyQQsrvDlg) 
// ON_WM_SYSCOMMAND() 
// ON_WM_PAINT() 
// ON_WM_QUERYDRAGICON() 
ON_MESSAGE(UM_SOCK,OnSock) 
// ON_BN_CLICKED(IDC_BTN_SEND, OnBtnSend) 
//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
BOOL bchar=FALSE;//密碼檢測結果 
SOCKET m_socket; 
void CSkyQQsrvDlg::OnSock(WPARAM wParam,LPARAM lParam) 

switch(LOWORD(lParam)) 

case FD_READ:  //讀取事件 
  WSABUF wsabuf; 
  wsabuf.buf=new char[200]; 
  wsabuf.len=200; 
  DWORD dwRead; 
  DWORD dwFlag=0; 
  SOCKADDR_IN addrFrom; 
  int len=sizeof(SOCKADDR); 
  CString str; 
  CString strTemp; 
  HOSTENT *pHost; 
  if(SOCKET_ERROR==WSARecvFrom   (m_socket,&wsabuf,1,&dwRead,&dwFlag,//WSARecvFrom接受資料函數 
      (SOCKADDR*)&addrFrom,&len,NULL,NULL)) 
  { 
   MessageBox("接收資料失敗!"); 
   return; 
  } 
  pHost=gethostbyaddr((char*)&addrFrom.sin_addr.S_un.S_addr,4,AF_INET); 
  addrFromIP.sin_addr.S_un.S_addr=addrFrom.sin_addr.S_un.S_addr; 
  char(wsabuf.buf);//調用密碼檢測函數 
CString strSend; 
if(bchar) 
{//發送驗證成功的消息 
  strsend="success"; 

else    strsend="FALSE"; 
SOCKADDR_IN addrTo; 
addrTo.sin_family=AF_INET; 
addrTo.sin_addr.S_un.S_addr=addrFromIP.sin_addr.S_un.S_addr; 
addrTo.sin_port=Port;//將獲取的資料埠設置為發送資料埠 
len=strSend.GetLength();    //長度 
wsabuf.buf=strSend.GetBuffer(len); 
wsabuf.len=len+1; 
if(SOCKET_ERROR==WSASendTo(m_socket,&wsabuf,1,&dwSend,0, //WSASend發送資料 
   (SOCKADDR*)&addrTo,sizeof(SOCKADDR),NULL,NULL)) 

  MessageBox("發送資料失敗!"); 
  return; 



void char(char * wsabuf) 

_ConnectionPtr m_pConnection; 
_RecordsetPtr m_pRecordset 
CString admin,passwd; 
huanyuan(wsabuf,admin,passwd); 
//假設伺服器上已經有一個ACCESS資料庫檔,檔案名為skywd,並建有user(admin,password)表 
//初始話OLE/COM庫環境 
::CoInitialize(NULL); 
try 

_ConnectionPtr pConn(__uuidof(Connection)); 
pConn->C; 
pConn->Open("","","",adConnectUnspecified); //打開對資料庫的連接,使用者ID和密碼,同步打開這個連接 
m_pC; 

//捕捉異常 
catch(_com_error e) 
{   //顯示錯誤資訊 
//  AfxMessageBox(e.Description()); 
  AfxMessageBox("資料庫連接出錯"); 

//設置INSERT語句,查詢資料 
_bstr_t vSQL; 
vSQL = "SELECT * FROM user WHERE admin = '" +admin + "'" ; //變數直接加,字串用""括起來 
try 

m_pRecordset.CreateInstance(__uuidof(Recordset)); 
m_pRecordset->Open(vSQL,m_pConnection.GetInterfacePtr(), //直接用記錄集物件查詢 
adOpenDynamic,adLockOptimistic,adCmdText); 

catch(_com_error e) 

  AfxMessageBox(e.Description()); 

_variant_t  var = m_pRecordset->GetCollect("password"); 
  if(var.vt!=VT_NULL) 
  { 
   if(passwd==(LPCTSTR)_bstr_t(var)) 
   bchar=TRUE;//通過驗證 
  } 
  else 
  { //如果答案為空,則重建答案 
   bchar=FALSE; 
  } 
//斷開資料庫連接 
if(m_pRecordset!=NULL) 
m_pRecordset->Close(); 
m_pConnection->Close(); 


zhuanhuan(char * wsabuf,CString admin,CString passwd)
{
    CString str1=wsabuf;
    int n1=str1.Find(":");
    int n2=str1.Find(",");
    int n3=str1.Getlength()-1;
    admin=str1.Left(n2);
    admin=admin.Right(n2-n1-1);
    passwd=str1.Right(n3-n2-1);
}

 

arrow
arrow
    全站熱搜

    殘月影 發表在 痞客邦 留言(1) 人氣()