Картина такая
Есть 3 приложения A/B/C
Приложения А конечное оно имеет доступ в сеть
Приложение В промежуточное оно переадресует траф с приложения А на С и наоборот
Приложения С - клиент.
Проблема видимо в синхронизации. вот примеры кода
Для приложения А
для Приложения В
суть в следующем ограничения буфера 8191 байт припустим нужно что то принят более чем этот буфер получается следущая ситуация приложения С принимает даные через прилож. В (в цикле по событиях перебрасывает буфер ) с прилож. А на прилож. С. Тут А начинает принимать даные и передавать на промежутоное приложение В но данные не все доходят с А на В, Тоесть смотрел в отладке А принимает все даные и сразу по событию отсылает на В. Прилож. B теряет даные так как идет следующая ситуация А принимает даные и отсылает и неизвестно как там В с ними работает принял или нет но в В не все даные что А принял. Какие методы синхронизации существуют в моем случае ??? или может есть у кого то исходники тунеля на винсок под винду ... я думал что бы все сразу принял а потом передавать но если у меня будет поток )) и т.д и т.п.
Есть 3 приложения A/B/C
Приложения А конечное оно имеет доступ в сеть
Приложение В промежуточное оно переадресует траф с приложения А на С и наоборот
Приложения С - клиент.
Проблема видимо в синхронизации. вот примеры кода
Для приложения А
Код:
// tunneling socket to socket :))
WSAEVENT MyStructEvents[1];
MyStructEvents[0] = hDestSockEvent;
MyStructEvents[1] = hSourceSocketEvent;
char*szBuf = (char*)GlobalAlloc(GMEM_ZEROINIT,TRANSFERS_BUFF);
if (szBuf != NULL)
{
DWORD dwRet;
int _recvBytes;
BOOL bIsExit = TRUE;
while (bIsExit)
{
WSANETWORKEVENTS WSANetworkEvents;
dwRet = WSAWaitForMultipleEvents(2,MyStructEvents,FALSE,TIME_WAIT_REPLY,FALSE);
switch (dwRet)
{
case WSA_WAIT_EVENT_0 + 0:
if (WSAEnumNetworkEvents(DestSock,hDestSockEvent,&WSANetworkEvents) == 0)
{
if(WSANetworkEvents.lNetworkEvents & FD_READ)
{
if (WSANetworkEvents.iErrorCode[FD_READ_BIT] == 0)
{
//do {
// receive data from remote server
_recvBytes = ReceiveData(DestSock,szBuf,TRANSFERS_BUFF);
if (_recvBytes > 0)
{
//send data to daemon
SendData(SourceSocket,szBuf,_recvBytes);
}
//} while (_recvBytes != 0);
}
}
if(WSANetworkEvents.lNetworkEvents & FD_CLOSE)
{
if ( (WSANetworkEvents.iErrorCode[FD_CLOSE_BIT] == 0) || (WSANetworkEvents.iErrorCode[FD_CLOSE_BIT] != 0))
{
bIsExit = FALSE;
}
}
}
break;
case WSA_WAIT_EVENT_0 + 1:
if (WSAEnumNetworkEvents(SourceSocket,hSourceSocketEvent,&WSANetworkEvents) == 0)
{
if(WSANetworkEvents.lNetworkEvents & FD_READ)
{
if (WSANetworkEvents.iErrorCode[FD_READ_BIT] == 0)
{
//do {
// receive data from daemon
_recvBytes = ReceiveData(SourceSocket,szBuf,TRANSFERS_BUFF);
if (_recvBytes > 0)
{
// send data to server
SendData(DestSock,szBuf,_recvBytes);
}
//} while (_recvBytes != 0);
}
}
if(WSANetworkEvents.lNetworkEvents & FD_CLOSE)
{
if ( (WSANetworkEvents.iErrorCode[FD_CLOSE_BIT] == 0) || (WSANetworkEvents.iErrorCode[FD_CLOSE_BIT] != 0))
{
bIsExit = FALSE;
}
}
}
break;
case WSA_WAIT_FAILED :
bIsExit = FALSE;
break;
}
}
GlobalFree(szBuf);
}
для Приложения В
Код:
hWsaEvents[0] := hClientRemoteEvent;
hWsaEvents[1] := hPeerBackConnectRemoteEvent;
GetMem(pTransferData,PACKET_BUFFER);
FillChar(pTransferData^,PACKET_BUFFER,0);
repeat
dwRet:=WSAWaitForMultipleEvents(2,@hWsaEvents,FALSE,WSA_TIMEOUT_DELAY,FALSE);
case dwRet of
WSA_WAIT_EVENT_0 + 0:
begin
if WSAEnumNetworkEvents(MySocketsInfo.sClientRemoteSocket,hClientRemoteEvent,MyWSANetworkEvents) = 0 then
begin
if ( MyWSANetworkEvents.lNetworkEvents and FD_READ) > 0 then
begin
if MyWSANetworkEvents.iErrorCode[FD_READ_BIT] = 0 then
begin
//repeat
// receive from client
dwReceiveBytes := ReceiveData(MySocketsInfo.sClientRemoteSocket,PAnsiChar(pTransferData),PACKET_BUFFER);
if (dwReceiveBytes > 0) then
begin
// send to bot
SendData(sPeerBackConnectRemoteSocket,PAnsiChar(pTransferData),dwReceiveBytes);
end;
//until (dwReceiveBytes = 0);
end;
end;
if ( MyWSANetworkEvents.lNetworkEvents and FD_CLOSE) > 0 then
begin
if (MyWSANetworkEvents.iErrorCode[FD_CLOSE_BIT] = 0) or (MyWSANetworkEvents.iErrorCode[FD_CLOSE_BIT] <> 0) then
begin
// close subsession session
//bIsExitOrNext := True;
end;
end;
end;
end;
WSA_WAIT_EVENT_0 + 1:
begin
if WSAEnumNetworkEvents(sPeerBackConnectRemoteSocket,hPeerBackConnectRemoteEvent,MyWSANetworkEvents) = 0 then
begin
if ( MyWSANetworkEvents.lNetworkEvents and FD_READ) > 0 then
begin
if MyWSANetworkEvents.iErrorCode[FD_READ_BIT] = 0 then
begin
//repeat
// receive from bot
dwReceiveBytes := ReceiveData(sPeerBackConnectRemoteSocket,PAnsiChar(pTransferData),PACKET_BUFFER);
// send to client
if dwReceiveBytes > 0 then
begin
SendData(MySocketsInfo.sClientRemoteSocket,PAnsiChar(pTransferData),dwReceiveBytes);
end;
//until ( dwReceiveBytes = 0);
end;
end;
if ( MyWSANetworkEvents.lNetworkEvents and FD_CLOSE) > 0 then
begin
if (MyWSANetworkEvents.iErrorCode[FD_CLOSE_BIT] = 0) or (MyWSANetworkEvents.iErrorCode[FD_CLOSE_BIT] <> 0) then
begin
// close subsession session
//bIsExitOrNext := True;
end;
end;
end;
end;
WSA_WAIT_FAILED :
begin
bIsExitOrNext := True;
end;
end;
until (Self.Terminated or bIsExitOrNext);
FreeMem(pTransferData);
суть в следующем ограничения буфера 8191 байт припустим нужно что то принят более чем этот буфер получается следущая ситуация приложения С принимает даные через прилож. В (в цикле по событиях перебрасывает буфер ) с прилож. А на прилож. С. Тут А начинает принимать даные и передавать на промежутоное приложение В но данные не все доходят с А на В, Тоесть смотрел в отладке А принимает все даные и сразу по событию отсылает на В. Прилож. B теряет даные так как идет следующая ситуация А принимает даные и отсылает и неизвестно как там В с ними работает принял или нет но в В не все даные что А принял. Какие методы синхронизации существуют в моем случае ??? или может есть у кого то исходники тунеля на винсок под винду ... я думал что бы все сразу принял а потом передавать но если у меня будет поток )) и т.д и т.п.