const
MAX_BUF_SIZE=8192; //8192
type
//数据转发器数据结构
PRepeatDataBuffer=^stRepeatDataBuffer;
stRepeatDataBuffer=record //转发数据缓冲区
oh:stOrderHeader; //数据包头定义
targetSocket:TCustomWinSocket; //转发目标socket
buf:array[0..MAX_BUF_SIZE-1] of byte; //数据缓冲区
end;
//异步数据转发关键代码:
procedure TDM.ssData1ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
oh:stOrderHeader;//包头;
pBuf:pRepeatDatabuffer; //数据缓冲区结构
requestLen,recvLen:integer;
begin
recvLen:=socket.ReceiveLength;
if(recvLen=0)then exit;
if(socket.Data=nil)then //未分配数据块
begin
socket.ReceiveBuf(oh,sizeof(oh)); //接收数据头
if(not uOrder.VerifyOH(oh))then exit; //检验包头
getmem(pBuf,sizeof(stRepeatDatabuffer)); //分配 数据块;
zeromemory(pBuf,sizeof(stRepeatDatabuffer));
pBuf^.oh:=oh;
socket.Data:=pBuf; //socket链接数据块
if(oh.len=0)thenexit;
pBuf^.targetSocket:=getSocket(oh.pid,ssData1); //查找转发目标socket
if pBuf^.targetSocket=nil then begin socket.Close;exit;end;
pBuf^.targetSocket.SendBuf(oh,sizeof(stOrderHeader)); //发送包头
recvLen:=recvLen-sizeof(stOrderHeader);
if(recvLen=0)then exit;
end else begin
pBuf:=socket.Data; //数据块地址
end;
recvLen:=socket.ReceiveBuf(pBuf^.buf,MAX_BUF_SIZE); //接收数据并转发
if(recvLen=-1)then exit;
if(pBuf^.targetSocket.Connected)then
begin
recvLen:=pBuf^.targetSocket.SendBuf(pBuf^.buf,recvLen); //发送到目标socket
end;
end;
//根据id查找socket
function TDM.getSocket(id:DWORD;ServerSocket:TServerSocket):TCustomWinSocket;
var
i:integer;
poh:POrderHeader;
begin
result:=nil;for I := 0 to ServerSocket.Socket.ActiveConnections-1 do
begin
poh:=ServerSocket.Socket.Connections[i].Data;
if(poh=nil)then continue;
if(poh^.id=Id)then
begin
result:=ServerSocket.Socket.Connections[i];exit;
end;
end;
end;
//断开连接时释放缓冲区
procedure TDM.ssData1ClientDisconnect(Sender: TObject;Socket: TCustomWinSocket);
begin
if socket.Data<>nil then
begin
freemem(socket.Data);
socket.Data:=nil;
end;
fmain.LogMain('ssData1ClientDisconnect:'+socket.RemoteAddress);
end;
procedure TDM.ssData1ClientError(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
fMain.LogMain('ssData1ClientError:'+socket.RemoteAddress+':'+getSocketErr(ErrorEvent,ErrorCode));
ErrorCode:=0;
end;
//----------------------------------------------------------------------------------------
function tdm.getSocketErr(ErrorEvent: TErrorEvent;ErrorCode:integer):string;
var
sErrorCode,inf,sErrorEvent:string;
begin
sErrorCode:='错误代码:'+inttostr(ErrorCode);if ErrorEvent=eeConnect then
begin
sErrorEvent:='连接失败!';
end;if ErrorEvent=eeGeneral then
begin
sErrorEvent:='无法识别的错误!';
end;if ErrorEvent=eeSend then
begin
sErrorEvent:='发送数据失败!';
end;if ErrorEvent=eeReceive then
begin
sErrorEvent:='接受数据失败!';
end;if ErrorEvent=eeDisconnect then
begin
//DisCon(socket);
sErrorEvent:='关闭连接失败!';
end;if ErrorEvent=eeAccept then
begin
sErrorEvent:='接受连接失败!';
end;
inf:=sErrorEvent+sErrorCode;
result:=inf;
end;