Overlapped Pipe and synchronization function
Bonjour,
J'ai un problème similaire à une approche multi - client.
un service (server) tourne tout le temps et une ou plusieurs GUI (client) doivent communiquer avec le serveur.
Le serveur à un nom unique et chaque client définit son nom dynamiquement. le server à la possibilité d'avori ce nom.
le server et chaque client se chargent de creer un pipe en INBOUND et le lit quand un un message arrive.
Attention ce n'est pas du Dupleix car le server doit pouvoir parler avec chaque client de manière asynchrone and allant chercher leur pipe.
Le code est parfaitement adaptable en server et client dans le principe. et Le voici mais ça ne marche pas :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
|
void DispatcherRoot::initPlatformSpecificData()
{
mPlatformSpecificData = new DispatcherRootPlateformSpecificData_win();
((DispatcherRootPlateformSpecificData_win*)mPlatformSpecificData)->dispatcherRoot = this;
CString lPipeName("\\\\.\\pipe\\");
lPipeName += mName.c_str();
HANDLE htest = CreateNamedPipe(
lPipeName, // pipe name
PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, // read access
PIPE_TYPE_MESSAGE | // message type pipe
PIPE_READMODE_MESSAGE | // message-read mode
PIPE_WAIT, // blocking mode
PIPE_UNLIMITED_INSTANCES, // max. instances
BUFSIZE, // output buffer size
BUFSIZE, // input buffer size
0, // client time-out
NULL); // default security attribute
/// creation d'un event pour utiliser RegisterWaitForSingleObject
OVERLAPPED ovr;
HANDLE h = CreateEvent(
NULL, // default security attribute
TRUE, // manual-reset event
FALSE, // initial state = signaled
NULL); // unnamed event object
if (h == NULL)
{
printf("CreateEvent failed with %d.\n", GetLastError());
return ;
}
ovr.hEvent = h;
//Since the hPipe was created with FILE_FLAG_OVERLAPPED
//and lpOverlapped in ConnectNamedPipe is not NULL,
//the OVERLAPPED structure should contain a handle to a manual-reset event object.
bool test = ConnectNamedPipe(htest,&ovr);
((DispatcherRootPlateformSpecificData_win*)mPlatformSpecificData)->hPipe = htest;
HANDLE hWait;
bool test2 = RegisterWaitForSingleObject(
&hWait,
((DispatcherRootPlateformSpecificData_win*)mPlatformSpecificData)->hPipe,
(WAITORTIMERCALLBACK)callback,
mPlatformSpecificData,
INFINITE,
WT_EXECUTEDEFAULT);
}
void DispatcherRoot::finalizePlatformSpecificData()
{
DisconnectNamedPipe(((DispatcherRootPlateformSpecificData_win*)mPlatformSpecificData)->hPipe);
CloseHandle(((DispatcherRootPlateformSpecificData_win*)mPlatformSpecificData)->hPipe);
delete mPlatformSpecificData;
} |
Code of the callback send and receive functions
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
|
void* callback(void* aArg)
{
DispatcherRootPlateformSpecificData_win* lPlatformSpecificData = (DispatcherRootPlateformSpecificData_win*)aArg;
ReadFromPipe(lPlatformSpecificData);
return NULL;
}
void DispatcherRoot::sendData(const std::string& aRootName, const std::string& aData,void* aPlatformData)
{
CString lPipeName("\\\\.\\pipe\\");
lPipeName += aRootName.c_str();
HANDLE lPipe =
CreateFile(
lPipeName, // pipe name
GENERIC_WRITE, // write access
0, // no sharing
NULL, // default security attributes
OPEN_EXISTING, // opens existing pipe
FILE_ATTRIBUTE_NORMAL, // default attributes
0); // no template file
if( lPipe == INVALID_HANDLE_VALUE )
{
LCTrace("CreatePipe failed");
return;
}
else
{
DWORD lByteWritten;
bool test = WriteFile(lPipe,(LPCTSTR)aData.c_str(),strlen(aData.c_str()),&lByteWritten,0);
if(test)
LCTrace("data written");
}
CloseHandle(lPipe);
}
void ReadFromPipe(DispatcherRootPlateformSpecificData_win* aPlatformData)
{
//Read client requests from the pipe.
BOOL lStatus= ReadFileEx(
((DispatcherRootPlateformSpecificData_win*)aPlatformData)->hPipe, // handle to the pipe created in Initialization
((DispatcherRootPlateformSpecificData_win*)aPlatformData)->buffer, // buffer to receive data in the same structure
BUFSIZE, // size of buffer
(LPOVERLAPPED)aPlatformData,
(LPOVERLAPPED_COMPLETION_ROUTINE) CompletedReadRoutine);
if( !lStatus )
LCTrace("could not setup read completion routine %d",GetLastError());
}
VOID WINAPI CompletedReadRoutine(DWORD dwErr, DWORD cbBytesRead, LPOVERLAPPED aOverlap)
{
DispatcherRootPlateformSpecificData_win* lPlatformData = (DispatcherRootPlateformSpecificData_win*) aOverlap;
if ((dwErr == 0) && (cbBytesRead != 0))
{
std::string lData = lPlatformData->buffer;
lPlatformData->dispatcherRoot->receivedData(lData,NULL);
}
} |
Quand je lance mon client et que j'écris par la fonction sendData mon server ne reçoit rien, il n'est pas alerter par l'écriture côté client.
j'ai éssyé sans l'overlapped ça roule mais le server est bien entendu bloqué sur une attente d'écriture côté client. et ce n'est pas ce que je veux.
Merci de m'aider les gars je suis bloqué
Robux