K
kintsoon
Unregistered / Unconfirmed
GUEST, unregistred user!
to all:
一般引起这边失败的原因都有哪些?
if (GetQueuedCompletionStatus(CompletionPort, BytesTransferred,
DWORD(PerHandleData), POverlapped(PerIoData), INFINITE) = False) then
begin
printf('GetQueuedCompletionStatus failed with error %d', GetLastError());
exit;
end;
刚开始可以正常接收,但是不知道为什么很快就会出现错误:
GetQueuedCompletionStatus failed with error 995
然后就没有办法在接收信息了.
我用的完成端口是网上现在到处都能找得到的,从Vc++翻译成Delphi的那个版本,然后稍微做了点修改.
完整版本:http://www.knowsky.com/336175.html
部分修改后代码如下:
function ServerWorkerThread(CompletionPortID: LPVOID): DWORD; stdcall;
var
CompletionPort: THANDLE;
BytesTransferred: DWORD ;
//Overlapped: POVERLAPPED;
PerHandleData: LPPER_HANDLE_DATA ;
PerIoData: LPPER_IO_OPERATION_DATA ;
SendBytes, RecvBytes: DWORD;
Flags: DWORD ;
RemoteCmd,cmd:string;
sNavFromUrl,sNavToUrl:string;
sUrlKey:string;
rcmd: TWSABUF ;
// rcmd: string;
begin
CompletionPort := THANDLE( CompletionPortID);
Result:= 0;
while(TRUE) do
begin
if (GetQueuedCompletionStatus(CompletionPort, BytesTransferred,
DWORD(PerHandleData), POverlapped(PerIoData), INFINITE) = False) then
begin
printf('GetQueuedCompletionStatus failed with error %d', GetLastError());
exit;
end;
// First check to see if an error has occured on the socket and if so
// then close the socket and cleanup the SOCKET_INFORMATION structure
// associated with the socket.
if (BytesTransferred = 0) then
begin
printf('Closing socket %d/', PerHandleData.Socket);
if (closesocket(PerHandleData.Socket) = SOCKET_ERROR) then
begin
printf('closesocket() failed with error %d', WSAGetLastError());
exit;
end;
GlobalFree(DWORD(PerHandleData));
GlobalFree(DWORD(PerIoData));
continue;
end;
// Check to see if the BytesRECV field equals zero. If this is so, then
// this means a WSARecv call just completed so update the BytesRECV field
// with the BytesTransferred value from the completed WSARecv() call.
if (PerIoData.BytesRECV = 0) then
begin
PerIoData.BytesRECV := BytesTransferred;
PerIoData.BytesSEND := 0;
end
else
begin
PerIoData.BytesSEND := PerIoData.BytesSEND + BytesTransferred;
end;
if (PerIoData.BytesRECV > PerIoData.BytesSEND) then
begin
// Post another WSASend() request.
// Since WSASend() is not gauranteed to send all of the bytes requested,
// continue posting WSASend() calls until all received bytes are sent.
ZeroMemory(@(PerIoData.Overlapped), sizeof(OVERLAPPED));
PerIoData.DataBuf.buf := PerIoData.Buffer + PerIoData.BytesSEND;
PerIoData.DataBuf.len := PerIoData.BytesRECV - PerIoData.BytesSEND;
//if (WSASend(PerHandleData.Socket, @(PerIoData.DataBuf), 1, @SendBytes, 0,
// @(PerIoData.Overlapped), nil) = SOCKET_ERROR) then
//从这边开始解析客户端传过来的数据
remotecmd:=PerIoData.Buffer;
cmd:='';
sNavFromUrl:='';
sNavToUrl:='';
sUrlKey:='';
//if writeLog='1' then
// fmMain.memo1.Lines.Append('received:'+remotecmd);
//////解析客户端传过来的命令//////////////
cmd := copy(remotecmd, 1, 2);
if (cmd='c:') or (cmd='d:') or (cmd='e:') or (cmd='f:') then //c:旧版,d:新版,e:金山,f:联盟
begin
if time='0' then exit; //如果时间为零,则直接退出。
if (cmd='f:') then
InsertCpuid(copy(remotecmd, 3, length(remotecmd)))
else if(copy(remotecmd, 3, 1)='m') then
InsertCpuid(cmd);
//if writeLog='1' then
// writeln('insert:'+copy(remotecmd, 3, 1));
if length('c:' + time)<BytesTransferred then
begin
rcmd.len:=BytesTransferred;
rcmd.buf:=pchar(StringOfChar(' ', BytesTransferred));
end
else
rcmd.len:=length('c:' + time);
rcmd.buf:=pchar('c:' + time);
end
else if (cmd='n:') or (cmd='o:') or (cmd='p:') then
begin
//if fmMain.edtTime.Text='0' then exit; //如果时间为零,则直接退出。
sNavFromUrl:=copy(remotecmd, 3, length(remotecmd));
if writeLog='1' then
writeln('received:'+remotecmd);
//先用全部匹配查找,找不到再用域名查找.
sNavToUrl:=GetNavToUrl(sNavFromUrl, sNavFromUrl, cmd);
if sNavToUrl='' then
begin
sUrlKey:=GetUrlKeys(sNavFromUrl);
//todo:如果是IP地址则返回空,否则返回其他。
//if writeLog='1' then
// writeln('key:'+sUrlKey);
if sUrlKey='' then exit;
sNavToUrl:=GetNavToUrl(sUrlKey, sNavFromUrl, cmd);
if sNavToUrl='' then exit;
end;
if length('n:' + sNavToUrl)<BytesTransferred then
begin
rcmd.len:=BytesTransferred;
rcmd.buf:=pchar(StringOfChar(' ', BytesTransferred));
end
else
rcmd.len:=length('n:' + sNavToUrl);
rcmd.buf:=pchar('n:' + sNavToUrl);
end;
///////////////////////////////////////////
if rcmd.len>0 then
begin
if writeLog='1' then
writeln('return:' + sNavToUrl);
//发送
if (WSASend(PerHandleData.Socket, @(rcmd), 1, @SendBytes, 0,
@(PerIoData.Overlapped), nil) = SOCKET_ERROR) then
begin
if (WSAGetLastError() <> ERROR_IO_PENDING) then
begin
printf('WSASend() failed with error %d', WSAGetLastError());
Exit;
end;
end;
end
//到这里结束
end
else
begin
PerIoData.BytesRECV := 0;
// Now that there are no more bytes to send post another WSARecv() request.
Flags := 0;
ZeroMemory(@(PerIoData.Overlapped), sizeof(OVERLAPPED));
PerIoData.DataBuf.len := DATA_BUFSIZE;
PerIoData.DataBuf.buf := @PerIoData.Buffer;
if (WSARecv(PerHandleData.Socket, @(PerIoData.DataBuf), 1, @RecvBytes, @Flags,
@(PerIoData.Overlapped), nil) = SOCKET_ERROR) then
begin
if (WSAGetLastError() <> ERROR_IO_PENDING) then
begin
printf('WSARecv() failed with error %d', WSAGetLastError());
exit;
end;
end;
end;
end;
end;
一般引起这边失败的原因都有哪些?
if (GetQueuedCompletionStatus(CompletionPort, BytesTransferred,
DWORD(PerHandleData), POverlapped(PerIoData), INFINITE) = False) then
begin
printf('GetQueuedCompletionStatus failed with error %d', GetLastError());
exit;
end;
刚开始可以正常接收,但是不知道为什么很快就会出现错误:
GetQueuedCompletionStatus failed with error 995
然后就没有办法在接收信息了.
我用的完成端口是网上现在到处都能找得到的,从Vc++翻译成Delphi的那个版本,然后稍微做了点修改.
完整版本:http://www.knowsky.com/336175.html
部分修改后代码如下:
function ServerWorkerThread(CompletionPortID: LPVOID): DWORD; stdcall;
var
CompletionPort: THANDLE;
BytesTransferred: DWORD ;
//Overlapped: POVERLAPPED;
PerHandleData: LPPER_HANDLE_DATA ;
PerIoData: LPPER_IO_OPERATION_DATA ;
SendBytes, RecvBytes: DWORD;
Flags: DWORD ;
RemoteCmd,cmd:string;
sNavFromUrl,sNavToUrl:string;
sUrlKey:string;
rcmd: TWSABUF ;
// rcmd: string;
begin
CompletionPort := THANDLE( CompletionPortID);
Result:= 0;
while(TRUE) do
begin
if (GetQueuedCompletionStatus(CompletionPort, BytesTransferred,
DWORD(PerHandleData), POverlapped(PerIoData), INFINITE) = False) then
begin
printf('GetQueuedCompletionStatus failed with error %d', GetLastError());
exit;
end;
// First check to see if an error has occured on the socket and if so
// then close the socket and cleanup the SOCKET_INFORMATION structure
// associated with the socket.
if (BytesTransferred = 0) then
begin
printf('Closing socket %d/', PerHandleData.Socket);
if (closesocket(PerHandleData.Socket) = SOCKET_ERROR) then
begin
printf('closesocket() failed with error %d', WSAGetLastError());
exit;
end;
GlobalFree(DWORD(PerHandleData));
GlobalFree(DWORD(PerIoData));
continue;
end;
// Check to see if the BytesRECV field equals zero. If this is so, then
// this means a WSARecv call just completed so update the BytesRECV field
// with the BytesTransferred value from the completed WSARecv() call.
if (PerIoData.BytesRECV = 0) then
begin
PerIoData.BytesRECV := BytesTransferred;
PerIoData.BytesSEND := 0;
end
else
begin
PerIoData.BytesSEND := PerIoData.BytesSEND + BytesTransferred;
end;
if (PerIoData.BytesRECV > PerIoData.BytesSEND) then
begin
// Post another WSASend() request.
// Since WSASend() is not gauranteed to send all of the bytes requested,
// continue posting WSASend() calls until all received bytes are sent.
ZeroMemory(@(PerIoData.Overlapped), sizeof(OVERLAPPED));
PerIoData.DataBuf.buf := PerIoData.Buffer + PerIoData.BytesSEND;
PerIoData.DataBuf.len := PerIoData.BytesRECV - PerIoData.BytesSEND;
//if (WSASend(PerHandleData.Socket, @(PerIoData.DataBuf), 1, @SendBytes, 0,
// @(PerIoData.Overlapped), nil) = SOCKET_ERROR) then
//从这边开始解析客户端传过来的数据
remotecmd:=PerIoData.Buffer;
cmd:='';
sNavFromUrl:='';
sNavToUrl:='';
sUrlKey:='';
//if writeLog='1' then
// fmMain.memo1.Lines.Append('received:'+remotecmd);
//////解析客户端传过来的命令//////////////
cmd := copy(remotecmd, 1, 2);
if (cmd='c:') or (cmd='d:') or (cmd='e:') or (cmd='f:') then //c:旧版,d:新版,e:金山,f:联盟
begin
if time='0' then exit; //如果时间为零,则直接退出。
if (cmd='f:') then
InsertCpuid(copy(remotecmd, 3, length(remotecmd)))
else if(copy(remotecmd, 3, 1)='m') then
InsertCpuid(cmd);
//if writeLog='1' then
// writeln('insert:'+copy(remotecmd, 3, 1));
if length('c:' + time)<BytesTransferred then
begin
rcmd.len:=BytesTransferred;
rcmd.buf:=pchar(StringOfChar(' ', BytesTransferred));
end
else
rcmd.len:=length('c:' + time);
rcmd.buf:=pchar('c:' + time);
end
else if (cmd='n:') or (cmd='o:') or (cmd='p:') then
begin
//if fmMain.edtTime.Text='0' then exit; //如果时间为零,则直接退出。
sNavFromUrl:=copy(remotecmd, 3, length(remotecmd));
if writeLog='1' then
writeln('received:'+remotecmd);
//先用全部匹配查找,找不到再用域名查找.
sNavToUrl:=GetNavToUrl(sNavFromUrl, sNavFromUrl, cmd);
if sNavToUrl='' then
begin
sUrlKey:=GetUrlKeys(sNavFromUrl);
//todo:如果是IP地址则返回空,否则返回其他。
//if writeLog='1' then
// writeln('key:'+sUrlKey);
if sUrlKey='' then exit;
sNavToUrl:=GetNavToUrl(sUrlKey, sNavFromUrl, cmd);
if sNavToUrl='' then exit;
end;
if length('n:' + sNavToUrl)<BytesTransferred then
begin
rcmd.len:=BytesTransferred;
rcmd.buf:=pchar(StringOfChar(' ', BytesTransferred));
end
else
rcmd.len:=length('n:' + sNavToUrl);
rcmd.buf:=pchar('n:' + sNavToUrl);
end;
///////////////////////////////////////////
if rcmd.len>0 then
begin
if writeLog='1' then
writeln('return:' + sNavToUrl);
//发送
if (WSASend(PerHandleData.Socket, @(rcmd), 1, @SendBytes, 0,
@(PerIoData.Overlapped), nil) = SOCKET_ERROR) then
begin
if (WSAGetLastError() <> ERROR_IO_PENDING) then
begin
printf('WSASend() failed with error %d', WSAGetLastError());
Exit;
end;
end;
end
//到这里结束
end
else
begin
PerIoData.BytesRECV := 0;
// Now that there are no more bytes to send post another WSARecv() request.
Flags := 0;
ZeroMemory(@(PerIoData.Overlapped), sizeof(OVERLAPPED));
PerIoData.DataBuf.len := DATA_BUFSIZE;
PerIoData.DataBuf.buf := @PerIoData.Buffer;
if (WSARecv(PerHandleData.Socket, @(PerIoData.DataBuf), 1, @RecvBytes, @Flags,
@(PerIoData.Overlapped), nil) = SOCKET_ERROR) then
begin
if (WSAGetLastError() <> ERROR_IO_PENDING) then
begin
printf('WSARecv() failed with error %d', WSAGetLastError());
exit;
end;
end;
end;
end;
end;