消息提示工具源码: 服务端: Msg.h /* * Create Date: 2004-12-01 * Create By: 李春雷 * purpose: 协议用自定义消息结构: * MESSAGEINFO:任务消息 * MsgType消息头:0xA登陆成功,0xB登陆失败,0xC工作消息,0xD任务结束标识 * LoginInfo:登陆消息 */
//------------------------------------------------------------------------------
struct MESSAGEINFO{ //消息结构 int MsgType; //消息头:0xA登陆成功,0xB登陆失败,0xC工作消息,0xD任务结束标识 char MessageID[10]; //任务序号 char UsrCode[10]; //用户帐号 //char TastName[50]; //任务名称 char TastName[200]; //任务名称 char CreatTime[20]; //时间 };
struct LoginInfo{ //登陆信息 char pwd[20]; //用户密码 char userID[30]; //用户ID }; //------------------------------------------------------------------------------
Unit1.cpp //---------------------------------------------------------------------------
#include <vcl.h> #pragma hdrstop #include "Unit1.h" #include "Unit2.h" #include "Msg.h" #include <iniFiles.hpp> //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; String myProvider;//数据库连接字符 int Port; //端口; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { IsServer=false; Server="localhost"; } //---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender) { // char dir[MAX_PATH]; //----获取运行程序的目录开始 char *tfile = "/Config.ini"; //将程序现在目录所在输入此字符数组 ::GetCurrentDirectory(MAX_PATH,dir); //将现在目录加上指定文件名 strcat(dir,tfile); //----获取运行程序的目录结束 TIniFile *ini = new TIniFile(dir); try { myProvider = ini->ReadString("servercfg","Provider","Provider=OraOLEDB.Oracle.1;Password=pwsc;Persist Security Info=True;User ID=developer;Data Source=dl;Extended Properties="""); Port = ini->ReadInteger("servercfg","port",1555); } catch(...) { MessageBox(Application->Handle,"读取配置文件config.ini失败!","信息提示!",MB_OK+MB_ICONINFORMATION+MB_SYSTEMMODAL); delete ini; } delete ini; ADOConnection1->ConnectionString = myProvider; ADOConnection1->LoginPrompt = false; try { ADOConnection1->Open(); } catch(...) { ShowMessage("无法连接数据库"); return; }
btndisconnect->Enabled=false; } //---------------------------------------------------------------------------
void __fastcall TForm1::btnlistenClick(TObject *Sender) { //程序运行后,如果用户按下"监听"钮, //则将该程序设为服务器端, //这时应将TServerSocket的Active属性设为True, //使服务器自动进入监听状态。 ServerSocket1->Port = Port; ServerSocket1->Active=true; StatusBar1->SimpleText="正在监听..."; btnlisten->Enabled=false; btndisconnect->Enabled=true;
} //--------------------------------------------------------------------------- void __fastcall TForm1::ClientSocket1Connect(TObject *Sender, TCustomWinSocket *Socket) { //当用户提出连接请求后,客户端会触发OnCreate事件, StatusBar1->SimpleText="连接到:"+Server; } //--------------------------------------------------------------------------- void __fastcall TForm1::ServerSocket1Accept(TObject *Sender, TCustomWinSocket *Socket) { //在服务器接受了客户的请求后会触发OnAccept事件, //在这个事件处理程序中将标志服务器端的变量IsServer设为True, IsServer=true; StatusBar1->SimpleText="连接到:"+Socket->RemoteAddress;
} //--------------------------------------------------------------------------- //---- 非阻塞传输方式,当其中的一方进行写操作时, //另一方会触发OnRead事件(客户端)或OnClientRead事件(服务器端), void __fastcall TForm1::ServerSocket1ClientRead(TObject *Sender, TCustomWinSocket *Socket) { LoginInfo *loginfo = new LoginInfo; Socket->ReceiveBuf(loginfo,50); String mySql = "select yhxh from xt_yh where yhbh='"; mySql+=loginfo->userID; mySql+="' and pwd='"; mySql+=loginfo->pwd; mySql+="'"; ADOQuery2->Close(); ADOQuery2->Connection = ADOConnection1; ADOQuery2->SQL->Clear(); ADOQuery2->SQL->Add(mySql); ADOQuery2->Open(); int num = ADOQuery2->RecordCount; MESSAGEINFO *LoginMsg = new MESSAGEINFO; int MsgType; if(num>0){ MsgType=0xA; //ok LoginMsg->MsgType=MsgType; }else{ MsgType=0xB; //nobody LoginMsg->MsgType=MsgType; } for(int i=0;i<ServerSocket1->Socket->ActiveConnections;i++){ if(ServerSocket1->Socket->Connections[i]->RemoteAddress==Socket->RemoteAddress) ServerSocket1->Socket->Connections[i]->SendBuf(LoginMsg,244); } ADOQuery2->Close();
} //--------------------------------------------------------------------------- void __fastcall TForm1::btndisconnectClick(TObject *Sender) { ServerSocket1->Close(); btnlisten->Enabled=true; btndisconnect->Enabled=false; } //--------------------------------------------------------------------------- void __fastcall TForm1::ServerSocket1ClientDisconnect(TObject *Sender, TCustomWinSocket *Socket) { StatusBar1->SimpleText="正在监听..."; } //--------------------------------------------------------------------------- void __fastcall TForm1::ClientSocket1Disconnect(TObject *Sender, TCustomWinSocket *Socket) { btnlisten->Enabled=true; btndisconnect->Enabled=false; StatusBar1->SimpleText=""; } //--------------------------------------------------------------------------- void __fastcall TForm1::ClientSocket1Error(TObject *Sender, TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode) { //---- 此外在客户端还应该增加错误捕获机制, //当用户输入无效的服务器名或服务器端没有 //处于监听状态时能够及时给用户反馈信息。 StatusBar1->SimpleText="无法连接到:"+Socket->RemoteHost; ErrorCode=0; } //---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender) { try{ if(ADOConnection1->Connected){ String strmessage=""; ADOQuery1->Close(); ADOQuery1->Connection = ADOConnection1; ADOQuery1->SQL->Clear(); ADOQuery1->SQL->Add("select t.message_id as 序号,t.user_code as 责任人, t.message_title as 任务名称, to_char(t.create_time,'yyyy-mm-dd hh24:mi') as 时间, t.is_read as 是否阅读 from user_message t where t.is_read='F' and t.task_state = 'ASSIGN' order by t.message_id"); ADOQuery1->Open(); MESSAGEINFO *Msg = new MESSAGEINFO;
String MessageID; //任务序号 String UsrCode; //用户帐号 String TastName; //任务名称 String CreatTime; //时间 while(!ADOQuery1->Eof){ MessageID=ADOQuery1->FieldByName("序号")->AsString; UsrCode=ADOQuery1->FieldByName("责任人")->AsString; TastName=ADOQuery1->FieldByName("任务名称")->AsString; CreatTime=ADOQuery1->FieldByName("时间")->AsString; Msg->MsgType=0xC; memcpy(Msg->MessageID,MessageID.c_str(),MessageID.Length()+1); memcpy(Msg->UsrCode,UsrCode.c_str(),UsrCode.Length()+1); memcpy(Msg->TastName,TastName.c_str(),TastName.Length()+1); memcpy(Msg->CreatTime,CreatTime.c_str(),CreatTime.Length()+1); //对客户端发消息: for(int i=0;i<ServerSocket1->Socket->ActiveConnections;i++){ //ServerSocket1->Socket->Connections[i]->SendBuf(Msg,94); ServerSocket1->Socket->Connections[i]->SendBuf(Msg,244); Sleep(1); } ADOQuery1->Next(); } Msg->MsgType=0xD; //结束符号 for(int i=0;i<ServerSocket1->Socket->ActiveConnections;i++){ //ServerSocket1->Socket->Connections[i]->SendBuf(Msg,94); ServerSocket1->Socket->Connections[i]->SendBuf(Msg,244); Sleep(1); //停1ms很关键 } delete Msg; }else{ Timer1->Enabled=false; } } catch(...){ Application->MessageBox("访问数据库错误!请重新启动程序。",NULL,MB_OK); Application->Terminate(); } }
//---------------------------------------------------------------------------
void __fastcall TForm1::ServerSocket1ClientError(TObject *Sender, TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode) { ErrorCode=0; } //---------------------------------------------------------------------------
void __fastcall TForm1::N2Click(TObject *Sender) { Application->Terminate(); } //---------------------------------------------------------------------------
void __fastcall TForm1::N3Click(TObject *Sender) { FormAbout->ShowModal(); } //---------------------------------------------------------------------------
Unit1.h
//---------------------------------------------------------------------------
#ifndef Unit1H #define Unit1H //--------------------------------------------------------------------------- #include <Classes.hpp> #include <Controls.hpp> #include <StdCtrls.hpp> #include <Forms.hpp> #include <ComCtrls.hpp> #include <ExtCtrls.hpp> #include <ScktComp.hpp> #include <ADODB.hpp> #include <Db.hpp> #include <DBGrids.hpp> #include <Grids.hpp> #include <Menus.hpp> //--------------------------------------------------------------------------- class TForm1 : public TForm { __published: // IDE-managed Components TServerSocket *ServerSocket1; TPanel *Panel1; TButton *btnlisten; TButton *btndisconnect; TStatusBar *StatusBar1; TADOConnection *ADOConnection1; TADOQuery *ADOQuery1; TDBGrid *DBGrid1; TDataSource *DataSource1; TTimer *Timer1; TADOQuery *ADOQuery2; TGroupBox *GroupBox1; TMainMenu *MainMenu1; TMenuItem *N1; TMenuItem *N2; TMenuItem *N3; TMenuItem *N4; TMenuItem *N5; TMenuItem *N6; void __fastcall FormCreate(TObject *Sender); void __fastcall btnlistenClick(TObject *Sender); void __fastcall ClientSocket1Connect(TObject *Sender, TCustomWinSocket *Socket); void __fastcall ServerSocket1Accept(TObject *Sender, TCustomWinSocket *Socket); void __fastcall ServerSocket1ClientRead(TObject *Sender, TCustomWinSocket *Socket); void __fastcall btndisconnectClick(TObject *Sender); void __fastcall ServerSocket1ClientDisconnect(TObject *Sender, TCustomWinSocket *Socket); void __fastcall ClientSocket1Disconnect(TObject *Sender, TCustomWinSocket *Socket); void __fastcall ClientSocket1Error(TObject *Sender, TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode); void __fastcall Timer1Timer(TObject *Sender); void __fastcall ServerSocket1ClientError(TObject *Sender, TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode); void __fastcall N2Click(TObject *Sender); void __fastcall N3Click(TObject *Sender); private: // User declarations bool IsServer; //服务器标识 String Server; //服务器IP public: // User declarations __fastcall TForm1(TComponent* Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TForm1 *Form1; //--------------------------------------------------------------------------- #endif
Unit2.h //---------------------------------------------------------------------------
#include <vcl.h> #pragma hdrstop
#include "Unit2.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TFormAbout *FormAbout; //--------------------------------------------------------------------------- __fastcall TFormAbout::TFormAbout(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TFormAbout::Button1Click(TObject *Sender) { ModalResult = mrOk; } //---------------------------------------------------------------------------
Unit2.cpp //---------------------------------------------------------------------------
#include <vcl.h> #pragma hdrstop
#include "Unit2.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TFormAbout *FormAbout; //--------------------------------------------------------------------------- __fastcall TFormAbout::TFormAbout(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TFormAbout::Button1Click(TObject *Sender) { ModalResult = mrOk; } //---------------------------------------------------------------------------
以上是服务端socket程序 另外,服务端的配置文件Config.ini内容如下: [servercfg] Provider=Provider=OraOLEDB.Oracle.1;Password=pwsc;Persist Security Info=True;User ID=developer;Data Source=dl;Extended Properties="" Port=1555 
|