请大家来修正和优化delphi做的Socket程序(100)

  • 主题发起人 主题发起人 zylsoft
  • 开始时间 开始时间
Z

zylsoft

Unregistered / Unconfirmed
GUEST, unregistred user!
2.1.1. 网络通讯协议IVR平台与SP双方交换数据需要通过网络来传输,网络传输协议采用TCP/IP协议,双方的通讯进程在TCP协议之上使用SOCKET连接,具体连接方式为短连接方式。由客户端主动发起连接请求,并在收到服务端的应答后切断连接。2.1.2. 数据定义2.1.2.1. 数据类型定义类型名称 对应标准C语言类型 字节数 说明WORD unsigned short 2 BYTE unsigned char 1 BYTEi unsigned char I DWORD unsigned long 4 INT Int 4 CHAR Char 1 2.1.2.2. 字节序定义本接口所定义的数据在网络中传输时,采用标准网络字节序(Big-Endian)。2.1.3. 消息头(Message Head)定义单元 长度 类型 说明Service ID 10 Bytei 业务代码Command ID 5 bytei 定义本条消息所对应的操作,见2.1.3.1Command Length 2 WORD 消息长度Server Process 2 WORD 本条消息目的应用进程标识。在各消息中定义。2.1.3.1. 各类操作的消息头定义操作 Command IDD3.1请求 10000 订购10010退订10020暂停10030恢复D3.1响应 10005订购10015退订10025暂停10035恢复 2.1.4. 接口说明2.1.4.1. 订购、退订、暂停、恢复业务请求消息请求消息定义:单元 长度 类型 说明 是否必须填Message Head 19 参见2.1.3中定义 是Sequence No. 14 BYTEi 由消息发起方分配的一个用于把请求消息与响应消息关联起来的序号:YYYYMMDD+序号 是Sub MDN 13 BYTEi 字符型 是USERNAME 12 BYTEi 用户名称 否PASSWORD 8 BYTEi 用户业务密码 否STARTTIME 20 BYTEi 请求时间(YYYY-MM-DD HH:MM:SS) 是VALIDTIME 20 BYTEi 订购有效时间(YYYY-MM-DD HH:MM:SS),仅对订购操作有效,默认不填写为一直有效 否FACTORY 2 WORD 受理渠道:1:营业厅,2:CRM门户,3:IVR 是PACKAGE 2 WORD 是否属于套餐订购的标志,0:非套餐,1:套餐 是PPFlag 1 BYTE 预付费标记:0:非预付费用户1:预付费用户 是OCS 21 BYTEi OCS号码 否ORDNO 16 BYTEi 工单流水号 否RESERVED 100 BYTEi 保留字段,对于一些web业务的开户会有特殊的定义字段,在这里传送,如有多个参数可用英文逗号“,”分隔 否响应消息定义:单元 长度 类型 说明Message Head 参见2.1.3中定义Sequence No. 14 BYTEi 由消息发起方分配的一个用于把请求消息与响应消息关联起来的序号Command Result 2 WORD 操作结果,0-成功;非0-见2.1.52.1.5. 操作结果定义值 含义0 成功2000 用户容量已满2001 用户MDN号码已存在2002 用户MIN号码已存在2005 用户不存在2006 用户号码非法2007 时间戳无效2008 操作员非法2009 参数错误2010 数据库操作错误2011 正在执行升位2012 写受理日志错误2013 语言属性错误(远端接口)3003 用户数据库断开3006 其他错误
 
unit xintai;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ScktComp, StdCtrls,winsock; //DWORD; 是4字接数 //WorD: 是2字接数 // BYTE 是1字接数 type STRUCT_hnqc_MSG_HEADER = ^TSTRUCT_hnqc_MSG_HEADER; TSTRUCT_hnqc_MSG_HEADER =packed record Service_ID :array[0..9] of Char; //业务代码 Command_ID : array[0..4] of Char; //定义本条消息所对应的操作 Command_Length:WORD; //消息长度 Server_Process : WORD ; //进程标识 end; type STRUCT_hnqc_SUBMIT = ^TSTRUCT_hnqc_SUBMIT; TSTRUCT_hnqc_SUBMIT =packed record Sequence_No : array[0..13] of Char; //YYYYMMDD+序号 Sub_MDN : array[0..12] of Char; // USERNAME : array[0..11] of Char;//用户名称 PASSWORD : array[0..7] of Char;//用户业务密码 STARTTIME : array[0..19] of Char;//请求时间 VALIDTIME: array[0..19] of Char;//订购有效时间 FACTORY:WORD; //受理渠道:1:营业厅,2:CRM门户,3:IVr PACKAGE:WORD; //是否属于套餐订购的标志,0:非套餐,1:套餐 PPFlag:BYTE;//预付费标记 OCS:array[0..20] of Char;//OCS号码 ORDNO:array[0..15] of Char;//工单流水号 RESERVED:array[0..99] of Char;//保留字段 end; type //响应消息全部 STRUCT_SUBMIT_RSP =^STRUCT_SUBMIT_RSP; TSTRUCT_SUBMIT_RSP = packed record sHeader : TSTRUCT_hnqc_MSG_HEADER ;//消息头 Sequence_No: array[0..13] of Char; // Command_Result : word; end; type STRUCT_SUBMIT = ^TSTRUCT_SUBMIT; TSTRUCT_SUBMIT = record sSubmitHeader : TSTRUCT_hnqc_MSG_HEADER ; //应用向应用平台提交短消息包头 hnqcSubmit : TSTRUCT_hnqc_SUBMIT ; //包体 end;implementationend.
 
unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,winsock, ComCtrls, ToolWin, ImgList, Menus, ExtCtrls;type TRecvThread = class(TThread) private // procedure CreateSocket(); procedure OnRecive(var ok : boolean); function SocketThread(): DWORD; protected procedure Execute; override; publicend;type TForm1 = class(TForm) Button2: TButton; Memo1: TMemo; MainMenu1: TMainMenu; N1: TMenuItem; N4: TMenuItem; N2: TMenuItem; N5: TMenuItem; N6: TMenuItem; N3: TMenuItem; N7: TMenuItem; ImageList1: TImageList; LightImg: TImageList; StatusBar1: TStatusBar; CoolBar1: TCoolBar; ToolBar1: TToolBar; TBClear: TToolButton; ToolButton3: TToolButton; TBActive: TToolButton; ToolButton1: TToolButton; TBTest: TToolButton; ToolButton2: TToolButton; TBAbout: TToolButton; ToolButton4: TToolButton; TBExit: TToolButton; Edit1: TEdit; Label1: TLabel; Label2: TLabel; Edit2: TEdit; Label3: TLabel; Edit3: TEdit; Timer1: TTimer; procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure FormCreate(Sender: TObject); procedure TBExitClick(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } thread : TRecvThread; public { Public declarations } end;var Form1: TForm1; Addr : TSockAddr; m_sock : TSocket; szPort :WORD;//端口 szADDR: array[0..63] of char;//IP //recvbufferIndex : Integer; //recvbuffer : array[0..4096] of Char; cachebuffer : array[0..4096] of Char; loop : Boolean; //接通平台标志 THESEQ_NO : integer;implementationuses xintai;{$R *.dfm}function GET_SEQ_NO():string;begin if THESEQ_NO >= 9999 then begin THESEQ_NO := 0 end else begin Inc(THESEQ_NO); end; result := FormatDatetime('YYYYMMDD', Now)+inttostr(THESEQ_NO);end;procedure memcpy(o, input : PChar; len : Integer);var i : integer;begin i := 0; while i < len do begin o := input; Inc(i); end;end;procedure TRecvThread.CreateSocket();begin GetPrivateProfileString ('Info', 'ADDRESS','', szADDR, sizeof(szADDR),'./SendMsg.ini'); szPort:=GetPrivateProfileInt('Info','APPPORT',0,'./SendMsg.ini'); m_sock := socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); Addr.sin_family := AF_INET; Addr.sin_port := htons(szPort); Addr.sin_addr := TInAddr(inet_addr(szADDR)); form1.Memo1.Lines.Add('准备链接平台>>>>>'); application.ProcessMessages; while 0 > connect(m_sock, Addr, sizeof(Addr)) do begin form1.Memo1.Lines.Add('平台链接失败,5秒后进行重链>>>>>'); loop:=false; sleep(5000);//5妙后重联 end; loop:=true;//平台链接ok while loop do begin OnRecive(loop) ;end;end;procedure TRecvThread.OnRecive(var ok : boolean);Var recvLen : Integer; submit_rsp: TSTRUCT_SUBMIT_RSP;begin FillChar(cachebuffer,SizeOf(cachebuffer),0); recvLen := recv( m_sock, cachebuffer, 4096, 0 ); if recvLen>0 then begin loop:=false;exit;end; memcpy(@submit_rsp, cachebuffer, recvLen); //Recv(ASocket,buf,SizeOf(buf),0); //接收数据 form1.Memo1.Lines.Add(string(submit_rsp.sHeader.Service_ID)); form1.Memo1.Lines.Add(string(submit_rsp.sHeader.Command_ID)); if string(submit_rsp.sHeader.Command_ID) = '10005' then begin form1.Memo1.Lines.Add('定购回应');end; if string(submit_rsp.sHeader.Command_ID) = '10015' then begin form1.Memo1.Lines.Add('退订回应');end; if string(submit_rsp.sHeader.Command_ID) = '10025' then begin form1.Memo1.Lines.Add('暂停回应');end; if string(submit_rsp.sHeader.Command_ID) = '10035' then begin form1.Memo1.Lines.Add('回复回应');end; form1.Memo1.Lines.Add('回应:'+string(@submit_rsp.Sequence_No)); form1.Memo1.Lines.Add('回应状态:'+inttostr(ntohl(submit_rsp.Command_Result))); //发送消息后断开 closesocket( m_sock ); Suspend(); Terminate(); CloseHandle(Handle);end;function TRecvThread.SocketThread(): DWORD;begin CreateSocket(); // end;procedure TRecvThread.Execute();begin SocketThread();end;procedure SubmitMsg(sock : TSocket;handset:string;Command_ID:string;starttime:string);var submit : TSTRUCT_SUBMIT;begin ZeroMemory(@submit,sizeof(submit)) ; fillchar(submit.sSubmitHeader.Service_ID,sizeof(submit.sSubmitHeader.Service_ID),ord(0)); strpcopy(submit.sSubmitHeader.Service_ID,'961681030') ; //业务代码 fillchar(submit.sSubmitHeader.Command_ID,sizeof(submit.sSubmitHeader.Command_ID),ord(0)); strpcopy( submit.sSubmitHeader.Command_ID,Command_ID) ; //定义本条消息所对应的操作 submit.sSubmitHeader.Command_Length:=htons(sizeof(submit.sSubmitHeader)+sizeof(submit.hnqcSubmit));//消息长度 submit.sSubmitHeader.Server_Process:=htons(1);//本条消息目的应用进程标识。在各消息中定义 // fillchar(submit.hnqcSubmit.Sequence_No,sizeof(submit.hnqcSubmit.Sequence_No),ord(0)); strpcopy( submit.hnqcSubmit.Sequence_No,GET_SEQ_NO()) ; //由消息发起方分配的一个用于把,流水号 fillchar(submit.hnqcSubmit.Sub_MDN,sizeof(submit.hnqcSubmit.Sub_MDN),ord(0)); strpcopy( submit.hnqcSubmit.Sub_MDN,handset) ; //字符型,应该是电话号码 fillchar(submit.hnqcSubmit.STARTTIME,sizeof(submit.hnqcSubmit.STARTTIME),ord(0)); strpcopy( submit.hnqcSubmit.STARTTIME,starttime) ; //请求时间 ;YYYY-MM-DD HH:MM:SS submit.hnqcSubmit.FACTORY:=htonl(3); //受理渠道 submit.hnqcSubmit.PACKAGE:=htonl(0); //是否属于套餐订购的标志 submit.hnqcSubmit.PPFlag:=0; //预付费标记 // send(sock,submit, ntohl(submit.sSubmitHeader.Command_Length), 0); form1.Memo1.Lines.Add('向平台提交一条Submit消息');end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);begin //断开 thread.Suspend(); thread.Terminate(); CloseHandle(thread.Handle); closesocket( m_sock ); WSACleanup; end;procedure TForm1.FormCreate(Sender: TObject);begin WSASetLastError( 0 ); edit3.Text:=FormatDatetime('YYYY-MM-DD HH:MM:SS', Now); THESEQ_NO:=0; loop:=false;end;procedure TForm1.TBExitClick(Sender: TObject);begin close;end;procedure TForm1.Button2Click(Sender: TObject);begin thread := TRecvThread.Create(false); if loop=true then begin //发送消息 SubmitMsg(m_sock,trim(edit1.Text),trim(edit2.Text),trim(edit3.Text)); //接收消息 end;end;end.
 
后退
顶部