TO: 各位大虾
1。TCP/IP 协议一定不能用,一定要用ZModem协议(领导规定,不必考虑说服他);
2。我们不用Modem池了,改用nPort;
3。效率问题暂时可以不考虑(领导意思),运行这个程序的服务器是4cpu,512Mram,且不干别的。
我把写的代码框架贴上来请大家帮忙看一下:
主窗口:
procedure TfrmGxtx.FormCreate(Sender: TObject);
Var
ComNumber:Integer;
TmpNode:TdxTreeListNode;
begin
MainView.BeginUpdate;
MainView.ClearNodes;
For ComNumber:= 1 To 1 Do begin
AvailPort[ComNumber]:=IsPortAvailable(ComNumber);
if AvailPort[ComNumber] then begin
TmpNode:=MainView.Add;
TmpNode.Values[0]:=ComNumber;
TmpNode.ImageIndex:=3;
CommHandle[ComNumber]:=TComm.Create(ComNumber);
end;
end;
MainView.EndUpdate;
For ComNumber:= 1 To 1 Do begin
If AvailPort[ComNumber] then CommHandle[ComNumber].Resume;
end;
end;
线程:
unit Comport;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls,
AdProtcl, AdModem, OoMisc, AdPort;
const
AM_STOP = WM_User + 100;
type
TComm = class(TThread)
private
SendOrRec:Boolean; // 状态量,False 接收;True 发送;
bIsAnswerFile:Boolean; // 正在回传的文件状态
StartTime:TDateTime;
ApdComPort:TApdComPort;
ApdModem:TApdModem;
ApdProToCol:TApdProToCol;
procedure ApdModemCommandProcessed(M: TObject;WhatHappened: TModemStatus; Data: Integer);
procedure ApdModemModemIsConnected(Sender: TObject);
procedure ApdProtocolProtocolStatus(CP: TObject; Options: Word);
procedure ApdComPortTriggerModemStatus(Sender: TObject);
procedure ApdProtocolProtocolFinish(CP: TObject; ErrorCode: Integer);
Procedure SetComStatus;
Procedure SetModemStatus;
Procedure SetFileTransmitStatus;
Procedure GetModem(M: TObject;WhatHappened: TModemStatus; Data: Integer);
protected
procedure Execute; override;
Public
Constructor Create(ComP:Integer);
end;
implementation
Uses Main,Common;
procedure TComm.ApdComPortTriggerModemStatus(Sender: TObject);
begin
If ApdComPort.DCD then begin
ApdComPort.SetStatusTrigger(DCDTrig[ApdComPort.ComNumber], msDCDDelta, True);
end else begin
if SendOrRec and bIsAnswerFile then begin
DCDTrig[ApdComPort.ComNumber] :=ApdComPort.AddStatusTrigger(stModem);
ApdComPort.SetStatusTrigger(DCDTrig[ApdComPort.ComNumber],msDCDDelta,True);
Exit;
end;
ApdComPort.SetStatusTrigger(DCDTrig[ApdComPort.ComNumber], msDCDDelta, True);
end;
end;
procedure TComm.ApdModemCommandProcessed(M: TObject;
WhatHappened: TModemStatus; Data: Integer);
begin
SendOrRec:=False;
ApdModem.AutoAnswer(2);
end;
procedure TComm.ApdModemModemIsConnected(Sender: TObject);
begin
ApdProToCol.StartReceive;
DCDTrig[ApdComPort.ComNumber]:=ApdComPort.AddStatusTrigger(stModem);
ApdComPort.SetStatusTrigger(DCDTrig[ApdComPort.ComNumber],msDCDDelta,True);
end;
procedure TComm.ApdProtocolProtocolFinish(CP: TObject; ErrorCode: Integer);
Var
Msg:TMsg;
begin
if SendOrRec or Terminated then begin
ApdModem.HangUp;
//DeleteFile(Pchar(ApdProToCol^.FileMask));
end else begin
SendOrRec:=True;
bIsAnswerFile:=Not bIsAnswerFile;
ModemStatus[ApdComport.ComNumber]:=sModemSetAnswer;
Synchronize(SetModemStatus);
While (Not FileExists(ApdProToCol.FileMask)) and (not Terminated) and (GetMessage(Msg,0,0,0)) and (Msg.message <> AM_STOP) Do DispatchMessage(Msg);
if (Not Terminated) or (Msg.message <> AM_STOP) then ApdProToCol.StartTransmit;
ModemStatus[ApdComport.ComNumber]:=sModemStartTransmit;
Synchronize(SetModemStatus);
end;
end;
procedure TComm.ApdProtocolProtocolStatus(CP: TObject; Options: Word);
begin
if Options= apFirstCall then begin
if SendOrRec then begin
ModemStatus[ApdComport.ComNumber]:=sModemStartTransmit;
Synchronize(SetModemStatus);
end else begin
ModemStatus[ApdComport.ComNumber]:=sModemStartReceive;
Synchronize(SetModemStatus);
end;
StartTime:=Time;
end;
if Options= apLastCall then begin
if SendOrRec then begin
ModemStatus[ApdComport.ComNumber]:=sModemEndTransmit;
Synchronize(SetModemStatus);
end else begin
ModemStatus[ApdComport.ComNumber]:=sModemEndReceive;
Synchronize(SetModemStatus);
end;
end;
FLength[ApdComport.ComNumber]:=ApdProToCol.FileLength;
FTransmit[ApdComport.ComNumber]:=ApdProToCol.bytesTransferred;
STime[ApdComport.ComNumber]:=Time - StartTime;
Speed[ApdComport.ComNumber]:=ApdComPort.Baud;
Persent[ApdComport.ComNumber]:=Trunc(ApdProToCol.bytesTransferred/ApdProToCol.FileLength*100);
Synchronize(SetFileTransmitStatus);
end;
constructor TComm.Create(ComP:Integer);
begin
SendOrRec:=False;
bIsAnswerFile:=False;
ApdComPort:=TApdComport.Create(Nil);
ApdComPort.ComNumber:=ComP;
ApdComPort.OnTriggerModemStatus:=ApdComPortTriggerModemStatus;
ApdModem:=TApdModem.Create(Nil);
ApdModem.ComPort:=ApdComPort;
ApdModem.OnCommandProcessed:=ApdModemCommandProcessed;
ApdModem.OnModemIsConnected:=ApdModemModemIsConnected;
ApdModem.OnModemEvent:=GetModem;
ApdProtocol:=TApdProtocol.Create(Nil);
ApdProToCol.ComPort:=ApdComPort;
ApdProToCol.OnProtocolStatus:=ApdProtocolProtocolStatus;
ApdProToCol.OnProtocolFinish:=ApdProtocolProtocolFinish;
inherited Create(True);
end;
procedure TComm.Execute;
Var
Msg:TMsg;
begin
Try
ApdModem.Initialize;
ModemStatus[ApdComport.ComNumber]:=sModemWait;
Synchronize(SetModemStatus);
Except
Status[ApdComport.ComNumber]:=2;
Synchronize(SetComStatus);
ModemStatus[ApdComport.ComNumber]:=sModemInitError;
Synchronize(SetModemStatus);
end;
while (not Terminated) and GetMessage(Msg,0,0,0) and (Msg.Message <> AM_STOP) do
DispatchMessage(Msg);
end;
procedure TComm.GetModem(M: TObject; WhatHappened: TModemStatus;
Data: Integer);
begin
Case WhatHappened Of
msModemOK:ModemStatus[ApdComport.ComNumber]:='A';
msModemConnect:ModemStatus[ApdComport.ComNumber]:='b';
msModemBusy:ModemStatus[ApdComport.ComNumber]:='c';
msModemVoice:ModemStatus[ApdComport.ComNumber]:='d';
msModemNoCarrier:ModemStatus[ApdComport.ComNumber]:='e';
msModemNoDialTone:ModemStatus[ApdComport.ComNumber]:='f';
msModemError:ModemStatus[ApdComport.ComNumber]:='g';
msGotLineSpeed:ModemStatus[ApdComport.ComNumber]:='h';
msGotErrCorrection:ModemStatus[ApdComport.ComNumber]:='i';
msGotDataCompression:ModemStatus[ApdComport.ComNumber]:='j';
msCmdTimeout:ModemStatus[ApdComport.ComNumber]:='k';
msDialTimeout:ModemStatus[ApdComport.ComNumber]:='l';
msAnswerTimeout:ModemStatus[ApdComport.ComNumber]:='m';
msDialCount: ModemStatus[ApdComport.ComNumber]:='n';
msAnswerCount:ModemStatus[ApdComport.ComNumber]:='o';
msModemRing: ModemStatus[ApdComport.ComNumber]:='p';
msModemIsConnected:ModemStatus[ApdComport.ComNumber]:='q';
msConnectFailed:ModemStatus[ApdComport.ComNumber]:='r';
end;
Synchronize(SetModemStatus);
end;
procedure TComm.SetComStatus;
begin
frmGxtx.MainView.Items[ComIndex[ApdComport.ComNumber]].ImageIndex:=Status[ApdComport.ComNumber];
end;
procedure TComm.SetFileTransmitStatus;
begin
frmGxtx.MainView.Items[ComIndex[ApdComport.ComNumber]].Values[2]:=FLength[ApdComport.ComNumber];
frmGxtx.MainView.Items[ComIndex[ApdComport.ComNumber]].Values[3]:=FTransmit[ApdComport.ComNumber];
frmGxtx.MainView.Items[ComIndex[ApdComport.ComNumber]].Values[4]:=TimeToStr(STime[ApdComport.ComNumber]);
frmGxtx.MainView.Items[ComIndex[ApdComport.ComNumber]].Values[5]:=Speed[ApdComport.ComNumber];
frmGxtx.MainView.Items[ComIndex[ApdComport.ComNumber]].Values[6]:=IntToStr(Persent[ApdComport.ComNumber])+'%';
end;
procedure TComm.SetModemStatus;
begin
frmGxtx.MainView.Items[ComIndex[ApdComport.ComNumber]].Values[1]:=ModemStatus[ApdComport.ComNumber];
end;
end.
问题(已知):
1。只能看到最后一个Modem.
2。触发ModemisConnect事件后程序不再继续。
我用了Apro控件。
当前环境是单机+2Modem