ciao a tutti
uso visual studio express 2012 c-c++
ho u problema con le named pipe.
Ho un named pipe in modalita overlapped
il server dopo essere entrato nel While spedisce un messaggio tramite la funzione WriteFile
poi aspetta 2 secondi e ritorna nel While
la CreateEvent e in manual reset,nel codice non c'e una funzione ResetEvent per cui
la funzione WaitForMultipleObject dovrebbe fermarsi ed attendere invece continua a spedire messaggi
Poi altro problema,Nel file Client Pipe quando entro nella funzione "chiudi" e creo un nuovo client il server non me lo segnala e continua a spedire messagg.i
in attesa di qualche risposta augoro buona giornata.
server.cpp
codice:
#include "stdafx.h"
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <conio.h>
#include <tchar.h>
#include <process.h> //for function _beginthreadEx
//#include <strsafe.h>
#include <iostream>
using namespace std;
#define NUM_PIPES 2
#define BUFFER_SIZE 256
unsigned __stdcall thWaitMessage(void *arg);
void main(void)
{
HANDLE hThread;
DWORD dwWait;
LPTSTR lpszPipeName = L"\\\\.\\PIPE\\myPipe";
hThread = (HANDLE)_beginthreadex(NULL,0,&thWaitMessage,(void*)lpszPipeName,0,NULL);
if(hThread == NULL)
{
cout << "\n_beginthreadEx Fallito, Errore " << GetLastError();
_getch();
return ;
}
dwWait = WaitForSingleObject(hThread,INFINITE);
cout << "\nfinito il thread,Premi un tasto per chiudere";
//thWaitMessage(LPTSTR lpszPipeName
_getch();
}
unsigned __stdcall thWaitMessage(void *arg)
{
HANDLE PipeHandles[NUM_PIPES];
//DWORD BytesTransferred;
//CHAR Buffer;//[NUM_PIPES][BUFFER_SIZE];
INT i;
OVERLAPPED Ovlap[NUM_PIPES];
HANDLE Event[NUM_PIPES];
WORD conta = 0;
DWORD Ret = 0;
DWORD numPipe;
TCHAR *Buffer = L"inviato dal server";
for (i = 0; i < NUM_PIPES; i++)
{
if ((Event[i] = CreateEvent(NULL,TRUE,TRUE,NULL)) == NULL)
{
cout << "\nCreateEvent for pipe failed with error "<< i << GetLastError();
_getch();
return 0;
}
// Create a named pipe instance
if ((PipeHandles[i] = CreateNamedPipe((LPCWSTR) arg,
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_MESSAGE | // message-type pipe
PIPE_READMODE_MESSAGE,
NUM_PIPES,
BUFFER_SIZE,BUFFER_SIZE,1000,NULL)) == INVALID_HANDLE_VALUE)
{
cout << "\nCreateNamedPipe for pipe with error " << i << GetLastError();
_getch();
return 0;
}
ZeroMemory(&Ovlap[i], sizeof(OVERLAPPED));
Ovlap[i].hEvent = Event[i];
Ovlap[i].Offset = 0;
Ovlap[i].OffsetHigh = 0;
// Listen for client connections using ConnectNamedPipe()
if(ConnectNamedPipe(PipeHandles[i], &Ovlap[i]) == 0)
{
if (GetLastError() != ERROR_IO_PENDING && GetLastError() != ERROR_PIPE_CONNECTED)
{
cout << "\nConnectNamedPipe for pipe " << i << " error " << GetLastError();
CloseHandle(PipeHandles[i]);
_getch();
return 0;
}
}
}
cout << "\nServer is now running";
while (1)
{
if((Ret = WaitForMultipleObjects(NUM_PIPES, Event,
false,INFINITE)) == WAIT_FAILED)
//Ret = WaitForMultipleObjects(NUM_PIPES, Event, FALSE, INFINITE);
{
cout << "\nWaitForMultipleObjects failed with error " << GetLastError();
_getch();
return 0;
}
numPipe = Ret - WAIT_OBJECT_0;
cout << "\nnumPipe = " << numPipe;
for(;;)
{
WORD err = WriteFile(PipeHandles[numPipe],(LPCVOID) Buffer,(wcslen(Buffer)+1)* sizeof(TCHAR), NULL, & Ovlap[numPipe]);
if (GetLastError() != ERROR_IO_PENDING)
{
cout << "\nWriteFile failed with error " << GetLastError();
}
DWORD r,rr = 0;
if (err && rr != ERROR_IO_PENDING)
break;
if (!GetOverlappedResult(PipeHandles[numPipe], &Ovlap[numPipe], &r, TRUE))
break;
Sleep(300);
}
wcout << endl << Buffer;
//SetEvent(Ovlap[numPipe].hEvent);// = Event[numPipe]);
Sleep(2000);
if(numPipe == 1)
break;
}
for(WORD c = 0;c < NUM_PIPES;c++)
{
if (DisconnectNamedPipe(PipeHandles[c]) == 0)
{
cout << "\nDisconnectNamedPipe failed with error " << GetLastError();
_getch();
return 0;
}
}
for(WORD i = 0; i < NUM_PIPES;i++)
{
CloseHandle(PipeHandles[i]);
CloseHandle(Event[i]);
}
_endthreadex(0);
return 0;
}
client.cpp
codice:
#include"stdafx.h"
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <process.h>
#include <conio.h>
using namespace std;
unsigned __stdcall clientPipe(void *);
bool chiudi(void);
#define INSTANCES 2
LPTSTR lpszPipeName = L"\\\\.\\PIPE\\myPipe";
int _tmain()
{
HANDLE hThread;
DWORD dwWait;
hThread = (HANDLE)_beginthreadex(NULL,0,&clientPipe,(void*)INSTANCES,0,NULL);
if(hThread == NULL)
cout << "\n_beginthreadEx Fallito, Errore " << GetLastError();
cout << "\nPremere un tasto per uscire";
_getch();
chiudi();
dwWait = WaitForSingleObject(hThread,INFINITE);
_getch();
}
unsigned __stdcall clientPipe(void *)
{
HANDLE hPipe;
DWORD dwRead = NULL;
TCHAR *buffer;
hPipe = CreateFile(lpszPipeName,
GENERIC_READ | GENERIC_WRITE,// | FILE_CREATE_PIPE_INSTANCE,
0,
NULL,
OPEN_EXISTING,
FILE_WRITE_ATTRIBUTES,
NULL);
if(hPipe == INVALID_HANDLE_VALUE)
{
cout << "\nErrore CreateFile";
return 0;
}
// The pipe connected; change to message-read mode.
DWORD dwMode = PIPE_READMODE_MESSAGE;
BOOL fSuccess = SetNamedPipeHandleState(
hPipe, // pipe handle
&dwMode, // new pipe mode
NULL, // don't set maximum bytes
NULL); // don't set maximum time
if(!fSuccess)
{
cout << "\nSetNamedPipeHandleState failed." << GetLastError();
return 0;
}
while(1)
{
buffer = new TCHAR [128];
BOOL ret = 0;
if(hPipe != INVALID_HANDLE_VALUE)
{
ret = ReadFile(hPipe,(TCHAR*) buffer,(wcslen(buffer)+1) * sizeof(TCHAR), &dwRead,NULL);
if(!ret)
{
ret = GetLastError();
if(ret == ERROR_PIPE_NOT_CONNECTED)
cout << "All'altra estremità del tubo non c'e' nessun processo,error numero " << ret;
_getch();
}
else
{
// add terminating zero
buffer[dwRead /sizeof(TCHAR)] = '\0';
cout << "\nbyte letti " << dwRead;
wcout << buffer << endl;
// controllo se devo uscire
if(wcscmp(buffer,L"Fine") == 0)
break;
}
}
delete buffer;
}
cout << "\nFINE";
CloseHandle(hPipe);
_endthreadex(0);
return 0;
}
// creo una seconda Pipe
bool chiudi(void)
{
cout << "\n sono nella fun chiudi";
HANDLE hPipeCh;
hPipeCh = CreateFile(lpszPipeName,
GENERIC_WRITE |GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if(hPipeCh == INVALID_HANDLE_VALUE)
{
return false;
}
return true;
}