急!!! 快吃不上饭了。(200分)

  • 主题发起人 主题发起人 LittleSong
  • 开始时间 开始时间
L

LittleSong

Unregistered / Unconfirmed
GUEST, unregistred user!
领导要求写一个通讯程序通过Modem连接,服务器端用Modem池,共有128个端口(电话),
要求使用多线程,有何好的实现办法。我有一套Async 3.0能不能用(客户端使用它做的)
 
好像不需要你写吧
 
添一句,只要服务器支持就可以了,反正不需要你操纵128个moden
 
128个端口相当于128个串口的,跟普通的没区别。
 
Modem池跟服务器有专用的交互方式,所以www说得不对
要是你的服务器里能看见128个端口,那就能用ASNC了:-)
 
问题在于,现在就是要我来操纵128个Modem,总不至于让我开128条线程吧。

另请问Async 稳定性如何(尤其在多线程下),他自带的多线程例子在我的机器
上不能用。
 
我的问题实际上是写一个程序在两台机器间通过modem拨号传文件,最多可以允许128台机器
同时向一台机器传输
 
兄弟,请你告诉我硬件是怎么架构的,
我想应该不会是128个串口直接连到你的服务器上吧
服务器跟modem pool是怎么接的?
 
肯定要用多线程啦,否则不可能实现的,但这么多个线程同时进行,效率肯定很低的。
Async没有用过,用过系统的同步机制实现多线程的同步与互斥感觉效率很低。
 
to:iie:我觉得服务器和Modem池的连接应可以不管,用控制面板可以查到所有串口,

另我用Async写的程序今天突然不好用了,他自带的例子也不好用了,会不会是没有注册的
原因,但我安装的时候没提示要注册号的。what,

 
真的?用控制面板查到128个串口??都占有独立的资源???
一个常识是PC的硬件端口地址空间1024,可128个16550接口就需要1024个地址,
难道除了串口就没有别的硬件了?
我在DOS时代也只做到了支持64个MODEM,那应该是极限了
 
To:iie:Sorry.我问了一下的确不是从控制面板上看到的,是用Modem池自带的控制程序
管理128个串口,但我看过以前别人写的程序用pdqcomm,单线程,管理32端口,似乎不必
考虑硬件连接问题,但以前的程序稳定性不太好难道和硬件有关?不知道。
 
根本与硬件无关,拨号网络一般建立在TCP/IP上.每个端口都对应一个IP地址,一旦客户机
拨通一个端口他就被指定了一个IP地址,而服务器也有一个IP,知道了你的IP和服务器IP.
两者之间通讯不用多说了吧.
 
Inter的HUB/路由器就支持modem拨号,且有Modem池
 
你还是先弄清硬件连接吧,我想你自己还没看到实际环境吧。
Modem Pool似乎不太适用你这样的应用,换Moxo的多串口服务器比较好。
另外,你应该考虑用TCP/IP协议群,而不是ZModem那种。
 
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
 
再问一下:win3.1 下的 WM_COMMNOTIFY 消息在win32下被什么消息替代了?

大虾们帮帮忙,如嫌分少只管开口。
 
问题不大,领导有些烦。基本的问题是通讯协议的问题,还有注意写程序要参照使用的产品
的型号等问题,对于此类问题的解决最好办法是参照别人已经写好的程序来检查自己的错误
要是担心饭碗的话,还是自己多努力,不然,哪里的好事在这里就解决呢?分有什么价值?
看你也是比较着急,问你,领导是做什么的呢?他懂多少技术上的事呢?对于此类的问题解
决的办法有很多种,如果你不是编程高手,也不必这么费心,找个简易的解决方法吧!!!
要是随便什么人写个程序也可以用的很好的话,那么我们编程的人吃什么饭啊!!你现在写
的程序还要调试的时间还长着呢!!即使能用也还很不稳定的,出问题的时候你可就、、、
也不想多说什么了,觉得你挺不容易的,如果想在编程上有什么作为的话,准备多掉几斤肉
吧!!!吃苦在前,也别想其他的,朋友给你个建议,吃自己的饭,走自己的路,自己的事
自己做!!靠人不如靠自己啊!!不好意思,说多了,见谅!!!
 
谢谢各位,问题我已经解决了,Apro 真好。
 

Similar threads

后退
顶部