本人要实现一个asp服务器控件Activex dll,它能够和主机进行传输文件.
当主机向dll控件连续发送数据时,控件中recv返回0没有收到数据.是不是数据发送太快了?activex中用winsock api,服务端用serversocket组件.已经郁闷了好久了,请各位高手大哥帮忙解改啊!Activex控件中接收数据:
procedure TShow.PlayVoice(const WavInfo, ip: WideString);
var
Trans:file of Byte;
Recelen:Integer;
BlockBuf:array[0..Blocklen-1] of Byte;
Cmd,CmdBuf:array[0..ResvLen-1] of char;
WavPath:string;
Host:String;
CA:SOCKADDR_IN;
HostAddr:U_LONG;
begin
try
StrPCopy(Cmd,'DOWN#'+WavInfo);
WavPath:=Server.MapPath('..\JK_Tel\JK_WAV')+'\'+ChangeFileExt(ExtractFileName(WavInfo),'.wav');
if FileExists(WavPath) then
begin
exit;
end;
Client:=Socket(PF_INET,SOCK_STREAM,IPPROTO_IP);
if Client =INVALID_SOCKET THEN
begin
Response.Write('创建Client失败!');
exit;
end;
CA.SIN_FAMILY:=PF_INET;
CA.SIN_PORT:=Htons(StrToInt('77777'));
Host:=WideCharToString(PWideChar(ip));
HostAddr:=INET_ADDR(PChar(Host));
CA.SIN_ADDR.S_ADDR:=HostAddr;
if Connect(Client,CA,SizeOf(CA)) <> 0 then
begin
Response.Write('连接'+ip+'服务器失败');
if WSACleanup<>0 then
Response.Write('清除WinSock失败!');
CloseSocket(Client);
exit;
end;
if send(Client,Cmd,SendLen,0)>0 then
begin
if Recv(Client,CmdBuf[0],ResvLen,0)>0 then
begin
if StrPas(CmdBuf)='NO' then
begin
if WSACleanup<>0 then
Response.Write('清除WinSock失败!');
CloseSocket(Client);
exit;
end;
end;
Recelen:=Recv(Client,BlockBuf,BlockLen,0);//这里接收不到数据,而在本机同时运行时,数据接收很正常.将服务端放到别的机子上,就收不到数据,返回0.AssignFile(Trans,WavPath);
ReWrite(Trans);
Response.Write(inttostr(Recelen));
while Recelen>0 do
begin
BlockWrite(Trans,BlockBuf[0],Recelen);
if Recelen<BlockLen then break;
Recelen:=Recv(Client,BlockBuf,BlockLen,0); end;
CloseFile(Trans);
end;
if WSACleanup<>0 then
Response.Write('清除WinSock失败!');
CloseSocket(Client);
except
end;
end;
server中发送:
if UpperCase(Cmd)='DOWN' then
begin
TelFile:=ResvList[1];
WavFile:=ExtractFilePath(TelFile)+ExtractFileName(TelFile)+'.wav';
if GX_AlawToWave(pchar(TelFile),pchar(WavFile)) = 0 then //将tel文件转化为wav
begin
ResvMsg:='YES';
StrPCopy(Msg,ResvMsg);
Socket.SendBuf(Msg,ResvLen);
AssignFile(Ftrans,WavFile);
Reset(Ftrans);
Flen:=FileSize(Ftrans);
BlockNum:=Flen div BlockLen;
RemainLen:=Flen mod BlockLen;
SendLen:=1;
for i:=0 to BlockNum-1 do
begin
if SendLen<=0 then break;
BlockRead(Ftrans,BlockBuf[0],BlockLen);
SendLen:=Socket.SendBuf(BlockBuf,BlockLen);
Application.ProcessMessages;
end;
if RemainLen>0 then
begin
BlockRead(Ftrans,BlockBuf[0],RemainLen);
SendLen:=Socket.SendBuf(BlockBuf,RemainLen);
end;
CloseFile(Ftrans);
if FileExiSts(WavFile) then
DeleteFile(WavFile);
end
else
begin
ResvMsg:='NO';
StrPCopy(Msg,ResvMsg);
Socket.SendBuf(Msg,ResvLen);
end;
end;
Socket.Close();
当主机向dll控件连续发送数据时,控件中recv返回0没有收到数据.是不是数据发送太快了?activex中用winsock api,服务端用serversocket组件.已经郁闷了好久了,请各位高手大哥帮忙解改啊!Activex控件中接收数据:
procedure TShow.PlayVoice(const WavInfo, ip: WideString);
var
Trans:file of Byte;
Recelen:Integer;
BlockBuf:array[0..Blocklen-1] of Byte;
Cmd,CmdBuf:array[0..ResvLen-1] of char;
WavPath:string;
Host:String;
CA:SOCKADDR_IN;
HostAddr:U_LONG;
begin
try
StrPCopy(Cmd,'DOWN#'+WavInfo);
WavPath:=Server.MapPath('..\JK_Tel\JK_WAV')+'\'+ChangeFileExt(ExtractFileName(WavInfo),'.wav');
if FileExists(WavPath) then
begin
exit;
end;
Client:=Socket(PF_INET,SOCK_STREAM,IPPROTO_IP);
if Client =INVALID_SOCKET THEN
begin
Response.Write('创建Client失败!');
exit;
end;
CA.SIN_FAMILY:=PF_INET;
CA.SIN_PORT:=Htons(StrToInt('77777'));
Host:=WideCharToString(PWideChar(ip));
HostAddr:=INET_ADDR(PChar(Host));
CA.SIN_ADDR.S_ADDR:=HostAddr;
if Connect(Client,CA,SizeOf(CA)) <> 0 then
begin
Response.Write('连接'+ip+'服务器失败');
if WSACleanup<>0 then
Response.Write('清除WinSock失败!');
CloseSocket(Client);
exit;
end;
if send(Client,Cmd,SendLen,0)>0 then
begin
if Recv(Client,CmdBuf[0],ResvLen,0)>0 then
begin
if StrPas(CmdBuf)='NO' then
begin
if WSACleanup<>0 then
Response.Write('清除WinSock失败!');
CloseSocket(Client);
exit;
end;
end;
Recelen:=Recv(Client,BlockBuf,BlockLen,0);//这里接收不到数据,而在本机同时运行时,数据接收很正常.将服务端放到别的机子上,就收不到数据,返回0.AssignFile(Trans,WavPath);
ReWrite(Trans);
Response.Write(inttostr(Recelen));
while Recelen>0 do
begin
BlockWrite(Trans,BlockBuf[0],Recelen);
if Recelen<BlockLen then break;
Recelen:=Recv(Client,BlockBuf,BlockLen,0); end;
CloseFile(Trans);
end;
if WSACleanup<>0 then
Response.Write('清除WinSock失败!');
CloseSocket(Client);
except
end;
end;
server中发送:
if UpperCase(Cmd)='DOWN' then
begin
TelFile:=ResvList[1];
WavFile:=ExtractFilePath(TelFile)+ExtractFileName(TelFile)+'.wav';
if GX_AlawToWave(pchar(TelFile),pchar(WavFile)) = 0 then //将tel文件转化为wav
begin
ResvMsg:='YES';
StrPCopy(Msg,ResvMsg);
Socket.SendBuf(Msg,ResvLen);
AssignFile(Ftrans,WavFile);
Reset(Ftrans);
Flen:=FileSize(Ftrans);
BlockNum:=Flen div BlockLen;
RemainLen:=Flen mod BlockLen;
SendLen:=1;
for i:=0 to BlockNum-1 do
begin
if SendLen<=0 then break;
BlockRead(Ftrans,BlockBuf[0],BlockLen);
SendLen:=Socket.SendBuf(BlockBuf,BlockLen);
Application.ProcessMessages;
end;
if RemainLen>0 then
begin
BlockRead(Ftrans,BlockBuf[0],RemainLen);
SendLen:=Socket.SendBuf(BlockBuf,RemainLen);
end;
CloseFile(Ftrans);
if FileExiSts(WavFile) then
DeleteFile(WavFile);
end
else
begin
ResvMsg:='NO';
StrPCopy(Msg,ResvMsg);
Socket.SendBuf(Msg,ResvLen);
end;
end;
Socket.Close();
解决方案 »
- dbgrid怎么直接赋值啊
- dll中如何使用 ExtractFilePath(application.exename);
- 我想用开发一个手机短信群发小系统,但是没有思路,高手帮我啊!
- 一个简单问题,让字段ID自动加1
- BDE怎么用
- 复制表结构?
- 一个图片中细胞,我如何数出其中的个数?
- 带孔压感纸打印问题:x希望打印几行记录之后纸张不自动走出空白部分
- 非主窗体如何保持总在最上层?
- 前辈们!!你们能告诉我怎样用delphi调用windows的浏览文件夹对话框吗????
- 请教个简单问题,怎么设置tquery的databasename的属性,加入我从一台电脑通过tquery向服务器插入数据。我对delphi不是很了解
- cxgird全方位的中文学习资料
文件也很小呀,就是Activex控件不知道怎么调试,主机上发送文件也很正常,控件就是接收不到数据,recv返回0.
还有,奇怪的是,我把服务端程序放到和注册activex的机子上运行,传输文件很正常.在单步调试服务端时,发现一步一步发送送据,控件就能收到数据.
可能本机速度快一点没问题,调试时等待时间够长也没问题.
将原来的发送
SendLen:=1;
for i:=0 to BlockNum-1 do
begin
if SendLen <=0 then break;
BlockRead(Ftrans,BlockBuf[0],BlockLen);
SendLen:=Socket.SendBuf(BlockBuf,BlockLen);
Application.ProcessMessages;
end; 改为
for i:=0 to BlockNum-1 do
begin
if SendLen<=0 then
begin
SLEEP(1);
SendLen:=Socket.SendBuf(BlockBuf,BlockLen);
Err:=inttostr(WSAGetLastError); //发现错误是10035,所以要重发一次
end;
BlockRead(Ftrans,BlockBuf[0],BlockLen);
SendLen:=Socket.SendBuf(BlockBuf,BlockLen);
SLEEP(1);
end;