?
首先利用vs来开发服务端:
第一步,打开Visual Studio新建一个win32控制台应用程序项目,名为login。
第二步,建立一个名为ifun的头文件,在这个文件里设计出服务端可供客服端调用的函数的函数头,其内容如下:
/**********************************************************************************************
编写头文件的几种特殊情况的处理已经注意点
1.所有的接口函数的名字必须以ns__开头
2.最后一个参数必须以指针或者引用的方式传递,作为客户端的返回值
3.需要传递的参数类型是一个结构体的时候,必须先要定义一个结构体 ,而且结构体的名字必须以ns__开头
4.当没有传入参数的时候参数类型定义为 void* 即可
***********************************************************************************************/
//登录接口
int ns__Login(char* strUserID,char* strPwd,wchar_t*& iLoginInfo);
//增加账户
int ns__Addid(char* strUserID,wchar_t*& iLoginInfo);
//删除账户
int ns__Deleteid(char* strUserID,wchar_t*& iLoginInfo);
//修改账户
int ns__Modifyid(char* strUserID,wchar_t*& iLoginInfo);
第三步,通过gsoap工具把ifun.h头文件自动生成一些与soap服务有关的文件。其具体步骤如下:
1,在D盘下新建一个名为gsoap的文件,将ifun.h头文件复制进来
2,打开gsoap工具的目录,例如:D:我的文档Visual Studio 2005gsoap-2.8gsoapbinwin32
3,打开doc命令,将工作目录改为D:/gsoap>再键入如下命令:
"D:我的文档Visual Studio 2005gsoap-2.8gsoapbinwin32soapcpp2.exe"? -i -S ifun.h再敲击回车
其生成视图为:

第四步,将这些自动生成的文件以及gsoap工具目录下的stdsoap2.h,stdsoap2.cpp文件添加进login项目,其中ns.wsdl放到debug文件夹下
第五步,继续编辑gsoap.cpp文件,在此文件的末尾编辑ifun.h文件中声明的函数的实现,实现的代码如下:
int Service::Login(char *strUserID,char *strPwd,wchar_t*& StrLoginInfo)
{
?_RecordsetPtr login_RecordSetPtr;
?CString userID;
?CString userPWD;
?CString userName;
?CString LoginInfo;
?CString strSQL;
?char* strReturnBuffer;
?static wchar_t WcharBuffer[WCHAR_MAX];
?memset(WcharBuffer,WCHAR_MAX);
?wchar_t* wchar_tArray = (wchar_t*)WcharBuffer;
?strSQL.Format("select * from login where myname = '%s'",strUserID);
?g_DataBase.IfOpenRecordset(login_RecordSetPtr);
?login_RecordSetPtr = g_DataBase.OpenReocrdset(strSQL);
?if(login_RecordSetPtr->adoEOF)
?{
??LoginInfo = Login_uderID_err;
??strReturnBuffer = LoginInfo.GetBuffer(LoginInfo.GetLength());
??LoginInfo.ReleaseBuffer();
??MBToWCHAR(wchar_tArray,strReturnBuffer,strlen(strReturnBuffer));
??StrLoginInfo = (wchar_t*)wchar_tArray;
??LoginInfo = Login_userPwd_err;??
??return SOAP_OK;
?}
?else
?{
???? strSQL.Format("select * from login where myname = '%s'and myage='%s'",strUserID,strPwd);
??g_DataBase.IfOpenRecordset(login_RecordSetPtr);
??login_RecordSetPtr = g_DataBase.OpenReocrdset(strSQL);
??if (login_RecordSetPtr->adoEOF)
??{
???LoginInfo = Login_userPwd_err;
??}
??else
??{
???LoginInfo.Format("%s",strUserID);??
??}
?}
?strReturnBuffer = LoginInfo.GetBuffer(LoginInfo.GetLength());
?MBToWCHAR(wchar_tArray,strlen(strReturnBuffer));
?LoginInfo.ReleaseBuffer();
?StrLoginInfo = (wchar_t*)wchar_tArray;
?g_DataBase.CloseRecordset(login_RecordSetPtr);
?return SOAP_OK;
}
int Service::Addid(char *strUserID,wchar_t *&iLoginInfo)
{
?_RecordsetPtr login_RecordSetPtr;
?CString userID;
?CString userPWD;
?CString userName;
?CString LoginInfo;
?CString strSQL;
?static wchar_t WcharBuffer[WCHAR_MAX];
?memset(WcharBuffer,WCHAR_MAX);
?wchar_t* wchar_tArray = (wchar_t*)WcharBuffer;
??strSQL.Format("insert into login (myname,myage) values ('%s','%s')",strPwd);
??g_DataBase.IfOpenRecordset(login_RecordSetPtr);
??login_RecordSetPtr = g_DataBase.OpenReocrdset(strSQL);
??MBToWCHAR(wchar_tArray,"添加成功",strlen("添加成功"));
??iLoginInfo = (wchar_t*)wchar_tArray;
?g_DataBase.CloseRecordset(login_RecordSetPtr);
?return SOAP_OK;
}
int Service::Deleteid(char *strUserID,wchar_t *&iLoginInfo)
{
?_RecordsetPtr login_RecordSetPtr;
?CString userID;
?CString userPWD;
?CString userName;
?CString LoginInfo;
?CString strSQL;
?char* strReturnBuffer;
?static wchar_t WcharBuffer[WCHAR_MAX];
?memset(WcharBuffer,strUserID);
?g_DataBase.IfOpenRecordset(login_RecordSetPtr);
?login_RecordSetPtr = g_DataBase.OpenReocrdset(strSQL);
?if (login_RecordSetPtr->adoEOF)
?{
??LoginInfo = Login_uderID_err;
??strReturnBuffer = LoginInfo.GetBuffer(LoginInfo.GetLength());
??LoginInfo.ReleaseBuffer();
??MBToWCHAR(wchar_tArray,strlen(strReturnBuffer));
??iLoginInfo = (wchar_t*)wchar_tArray;
?}
?else
?{
??strSQL.Format("delete from login where? myname = '%s'",strUserID);
??g_DataBase.IfOpenRecordset(login_RecordSetPtr);
??login_RecordSetPtr = g_DataBase.OpenReocrdset(strSQL);
??MBToWCHAR(wchar_tArray,"删除成功",strlen("删除成功"));
??iLoginInfo = (wchar_t*)wchar_tArray;
?}
?g_DataBase.CloseRecordset(login_RecordSetPtr);
?return SOAP_OK;
}
int Service::Modifyid(char *strUserID,WCHAR_MAX);
?wchar_t* wchar_tArray = (wchar_t*)WcharBuffer;
??? strSQL.Format("update login set myage='%s' where? myname = '%s'",strPwd,strUserID);
?g_DataBase.IfOpenRecordset(login_RecordSetPtr);
?login_RecordSetPtr = g_DataBase.OpenReocrdset(strSQL);
?MBToWCHAR(wchar_tArray,"修改成功",strlen("修改成功"));
?iLoginInfo = (wchar_t*)wchar_tArray;
?g_DataBase.CloseRecordset(login_RecordSetPtr);
?return SOAP_OK;
}
第六步,在login项目里加入头文件:CharConVert.h,Database.h,MailSender.h,Markup.h,PublicFunction.h以及源文件Markup.cpp,PublicFunction.cpp
第七步,编写stdafx.h文件以及主文件login.cpp其中主文件的内容如下:
// login.cpp : 定义控制台应用程序的入口点。
//
#include <vector>
#include "stdafx.h"
#include "Database.h"
#include "soapService.h"
#include "ns.nsmap"
#include "Markup.h"
#include "PublicFunction.h"
#include <stdio.h>
#include <string.h>
#include <iostream>
#include "MailSender.h"
#define PER_MINUTE (60000)
using namespace std;
int http_get(struct soap * soap);
CDataBase g_DataBase;
int _tmain(int argc,_TCHAR* argv[])
{
?//连接数据库
?if(!g_DataBase.OpenDatabase())
?{
??return 1;
?}
?Service calc;
?calc.imode |= SOAP_C_UTFSTRING;
?calc.omode |= SOAP_C_MBSTRING;
?calc.fget = http_get;
?if (!(argc < 2))
?{
??// serve as CGI application
??calc.serve();
??calc.destroy();
?}
?if (calc.run(9999))
?{
??calc.soap_stream_fault(std::cerr);
??exit(-1);
?}
?return 0;
}
//能够远程读取wsdl文件
int http_get(struct soap * soap)
{
?if (0 != strcmp(soap->path,"/ns.wsdl"))
?{
??return SOAP_GET_METHOD;
?}
?//读取硬盘wsdl文件
?CString cstrWsdlName = CPublicFunction::GetWsdlName();
?CString cstrWsdlPath = CPublicFunction::GetWsdlPath();
?CString cstrWsdl = cstrWsdlPath + cstrWsdlName;
?CMarkup xmlWsdl;
?string strWsdl;
?if(xmlWsdl.Load(cstrWsdl))
?{
??strWsdl = xmlWsdl.GetDoc();
??cout << strWsdl.c_str() <<endl;
?}
?soap->http_content = "xml";
?soap_response(soap,SOAP_FILE);
?soap_send_raw(soap,strWsdl.c_str(),strWsdl.length());??
?soap_end_send(soap);
?return SOAP_OK;
}
第八步,编译纠错,在login的属性页里加入预处理器定义:_AFXDLL,更改字符集为未设置,直到编译成功,服务端便完成了


? 最后通过flash builder开发客户端,其步骤如下:
第一步,打开flash builder,新建一个桌面应用程序项目,名也为login
第二步,在主文件里的设计视图中建立如下界面

第三步,进入源代码视图进行设计,代码为
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
??????? xmlns:s="library://ns.adobe.com/flex/spark"
??????? xmlns:mx="library://ns.adobe.com/flex/mx"
??????? xmlns:zp="zp.*"
??????? xmlns:ns1="*"
??????? width="800" height="385" accentColor="#0DA5BB"
??????? applicationComplete="windowedapplication1_applicationCompleteHandler(event)"
??????? backgroundColor="#D2F4F4" chromeColor="#4CEA1C">
?<fx:Style source="login.css"/>
?<fx:Script>
??<![CDATA[
???import ServiceManage.WebService.GService;
???import mx.controls.Alert;
???import mx.events.FlexEvent;
?? import mx.rpc.events.FaultEvent;
???import mx.rpc.events.ResultEvent;
???import mx.rpc.soap.LoadEvent;
???import mx.rpc.soap.WebService;
???private var m_gSer:GService;
???private var m_webser:WebService;
????? private var dkck:spark.components.WindowedApplication;
????public function OnRes(res:ResultEvent):void
???{
????Alert.show("OnRes");
???}???
???protected function dl_clickHandler(event:MouseEvent):void
???{
????m_webser.Login.addEventListener(ResultEvent.RESULT,OnLoginSuccess);
????m_webser.Login.addEventListener(FaultEvent.FAULT,OnLoginFault);
????m_webser.Login(sr1.text,sr2.text);????
???}?
???protected function jz_clickHandler(event:MouseEvent):void
???{
????m_webser.wsdl = "http://192.168.1.101:9999/ns.wsdl";??
????m_webser.addEventListener(ResultEvent.RESULT,OnRes);
????m_webser.addEventListener(FaultEvent.FAULT,OnFault);????
????m_webser.addEventListener(LoadEvent.LOAD,OnLoadWsdlSuccess);
????m_webser.loadWSDL();
???}
???
???protected function windowedapplication1_applicationCompleteHandler(event:FlexEvent):void
???{
????m_webser = new WebService;??
????jz_clickHandler(null);
???}
???public function OnLoadWsdlSuccess(e:LoadEvent):void
???{
????trace("-------OnLoadWsdlSuccess--------");??
????Alert.show("OnLoadWsdlSuccess");
???}
???public function OnFault(evt:FaultEvent):void
???{
????trace("-------OnLoadWsdlFault--------");
????Alert.show("OnLoadWsdlFault");
???}
???public function OnLoginSuccess(eve:ResultEvent):void
???{?
????Alert.show(eve.result.toString());
?????ck.enabled=true
???}
???public function OnLoginFault(eve:FaultEvent):void
???{
????Alert.show(eve.toString());
???}
???
???protected function qx_clickHandler(event:MouseEvent):void
???{
????// TODO Auto-generated method stub
????close();
???}???
???protected function zj_clickHandler(event:MouseEvent):void
???{
????// TODO Auto-generated method stub
????m_webser.Addid.addEventListener(ResultEvent.RESULT,OnAddidSuccess);
????m_webser.Addid.addEventListener(FaultEvent.FAULT,OnAddidFault);
????m_webser.Addid(sr3.text,sr4.text);?
???}
???public function OnAddidSuccess(eve:ResultEvent):void
???{???
????Alert.show(eve.result.toString());
???}
???public function OnAddidFault(eve:FaultEvent):void
???{
????Alert.show(eve.toString());
???}???
???protected function sc_clickHandler(event:MouseEvent):void
???{
????// TODO Auto-generated method stub
????m_webser.Deleteid.addEventListener(ResultEvent.RESULT,OnDeleteidSuccess);
????m_webser.Deleteid.addEventListener(FaultEvent.FAULT,OnDeleteidFault);
????m_webser.Deleteid(sr3.text,sr4.text);?
???}
???public function OnDeleteidSuccess(eve:ResultEvent):void
???{????
????Alert.show(eve.result.toString());
???}
???public function OnDeleteidFault(eve:FaultEvent):void
???{
????Alert.show(eve.toString());
???}???
???protected function xg_clickHandler(event:MouseEvent):void
???{
????// TODO Auto-generated method stub
????m_webser.Modifyid.addEventListener(ResultEvent.RESULT,OnModifyidSuccess);
????m_webser.Modifyid.addEventListener(FaultEvent.FAULT,OnModifyidFault);
????m_webser.Modifyid(sr3.text,sr4.text);
???}
???public function OnModifyidSuccess(eve:ResultEvent):void
???{????
????Alert.show(eve.result.toString());
???}
???public function OnModifyidFault(eve:FaultEvent):void
???{
????Alert.show(eve.toString());
???}???
??]]>
?</fx:Script>
?<fx:Declarations>
??<!-- 将非可视元素(例如服务、值对象)放在此处 -->
?</fx:Declarations>
?<s:HGroup x="10" y="85" width="288" height="46" gap="20" horizontalAlign="center">
??<s:Button id="dl" label="登陆" click="dl_clickHandler(event)"/>
??<s:Button id="qx" label="取消" click="qx_clickHandler(event)"/>
??<s:Button id="jz" height="21" label="加载" click="jz_clickHandler(event)"/>
?</s:HGroup>
?<s:VGroup x="6" y="28" width="80" height="45">
??<s:Label width="77" height="23" text="用户名:"/>
??<s:Label width="77" height="21" text="密码:"/>
?</s:VGroup>
?<s:VGroup x="60" y="28" width="130" height="53">
??<s:TextInput id="sr1"/>
??<s:TextInput id="sr2"/>
?</s:VGroup>
?<s:TitleWindow id="ck" x="352" y="101" width="375" height="256" enabled="false" title="账户管理">
??<s:HGroup x="6" y="3" width="200" height="27">
???<s:Label width="72" height="26" text="当前账户:"/>
??</s:HGroup>
??<s:VGroup x="6" y="38" width="68" height="77">
???<s:Button id="zj" label="增加账户" click="zj_clickHandler(event)"/>
???<s:Button id="xg" label="修改账户" click="xg_clickHandler(event)"/>
???<s:Button id="sc" label="删除账户" click="sc_clickHandler(event)"/>
??</s:VGroup>
??<s:Label x="10" y="135" width="76" height="19" text="账户名:"/>
??<s:Label x="10" y="158" width="82" height="19" text="密码:"/>
??<s:Image x="82" y="0" width="291" height="213" source="assets/00.jpg"/>
??<s:Label id="bj" x="88" y="3" width="77" height="26" text="{sr1.text}"/>
??<s:TextInput id="sr3" x="65" y="128"/>
??<s:TextInput id="sr4" x="65" y="158"/>
?</s:TitleWindow>
</s:WindowedApplication>
第四步,先运行先前编写好的服务端程序,再运行客户端进行测试,其结果如下:



到此时简单的登录系统便做成了,需要说明的是本系统的开发需要SQL2008数据库管理系统的支持。