本人要实现一个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();

解决方案 »

  1.   

    网络没问题,因为在传输文件之前就已经有过通信.我试了把两边的防火墙禁用了也不行.
    文件也很小呀,就是Activex控件不知道怎么调试,主机上发送文件也很正常,控件就是接收不到数据,recv返回0.
    还有,奇怪的是,我把服务端程序放到和注册activex的机子上运行,传输文件很正常.在单步调试服务端时,发现一步一步发送送据,控件就能收到数据.
      

  2.   

    在 Recelen:=Recv(Client,BlockBuf,BlockLen,0);之前加一句等待试试看. 会不会是数据还没传来.
    可能本机速度快一点没问题,调试时等待时间够长也没问题.
      

  3.   

    一直也没注意,原来是发送的时候出了问题.
    将原来的发送
    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;