Member 12711426 Ответов: 1

Как хранить данные в моей переменной m_buffer в моем клиентском приложении pipeserver


Я создал один канал сервер и клиентское приложение и проверил соединение между клиентом и сервером,
Сервер подключается, но не получает данные от клиента,

Мне нужно общаться с сервером и клиентом для отображения сообщений,

Не могли бы вы объяснить мне, как хранить данные в переменной m_buffer

Что я уже пробовал:

Вот мой серверный код


#include "StdAfx.h"
#include "PipeServer.h"
#include "process.h"
#include<Windows.h>
#include<tchar.h>


CPipeServer::CPipeServer(void)
{

}
CPipeServer::CPipeServer(std::wstring& sName):m_sPipeName(sName), 
                                                m_hThread(NULL), 
                                                m_nEvent(AU_INIT)
{
	 m_buffer = (wchar_t*)calloc(AU_DATA_BUF, sizeof(wchar_t));
    Init();
}

int CPipeServer::GetEvent() const
{
	return m_nEvent;
}
void CPipeServer::SetEvent(int nEventID)
{
	m_nEvent = nEventID;
}
HANDLE CPipeServer:: GetThreadHandle()
{
	return m_hThread;
}
HANDLE CPipeServer::GetPipeHandle()
{
	return m_hPipe;
}
void CPipeServer::SetData(std::wstring&  sData)
{
	 memset(&m_buffer[0], 0, AU_DATA_BUF);
	 wcsncpy(&m_buffer[0], sData.c_str(), __min(AU_DATA_BUF, sData.size()));
}
void CPipeServer::GetData(std::wstring& sData)
{
	sData.clear();
	sData.append(m_buffer);
}
void CPipeServer::Init()
{
	 if(m_sPipeName.empty())
    {
        LOG << "Error: Invalid pipe name" << std::endl;
        return;
    }
	 m_hPipe = CreateNamedPipe( m_sPipeName.c_str(),PIPE_ACCESS_DUPLEX,PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
								PIPE_UNLIMITED_INSTANCES,1024,1024, NMPWAIT_USE_DEFAULT_WAIT, NULL);
	 if(INVALID_HANDLE_VALUE == m_hPipe)
	 {
		 LOG<<"Error Could not created namedPipe"<<std::endl;
		 OnEvent(AU_ERROR);
	 }
	 else
	 {
		 OnEvent(AU_SERV_RUN);
	 }
	 Run();

}
void CPipeServer::OnBuffer(wchar_t* m_bufferID)
{

	m_buffer = m_bufferID;
}
void CPipeServer::Run()
{
	
    UINT uiThreadId = 0;
    m_hThread = (HANDLE)_beginthreadex(NULL,NULL,PipeThreadProc,this,CREATE_SUSPENDED,&uiThreadId);
	 if(NULL == m_hThread)
    {
        OnEvent(AU_ERROR);
    }
    else
    {
        SetEvent(AU_INIT);
        ::ResumeThread(m_hThread);
    }
}
UINT32 __stdcall CPipeServer::PipeThreadProc(void* pParam)
{
	CPipeServer* pPipe = reinterpret_cast<CPipeServer*>(pParam);
    if(pPipe == NULL)
        return 1L;
	pPipe->OnEvent(AU_THRD_RUN);
	while(true)
    {
        int nEventID = pPipe->GetEvent();
        if(nEventID == AU_ERROR || nEventID == AU_TERMINATE)
        {
           
            pPipe->Close();
            break;
        }

        switch(nEventID)
        {
        case AU_INIT:
            {
                pPipe->WaitForClient();
                break;
            }

        case AU_IOREAD:
            {
                if(pPipe->Read())
                    pPipe->OnEvent(AU_READ);
                else
                    pPipe->OnEvent(AU_ERROR);

                break;
            }

        case AU_IOWRITE:
            {
                if(pPipe->Write())
                    pPipe->OnEvent(AU_WRITE);
                else
                    pPipe->OnEvent(AU_ERROR);
            }
            break;

        case AU_CLOSE:
            {
                pPipe->OnEvent(AU_CLOSE);
                break;
            }

        case AU_IOWRITECLOSE:
            {
                if(pPipe->Write())
                    pPipe->OnEvent(AU_CLOSE);
                else
                    pPipe->OnEvent(AU_ERROR);

                break;
            }

        case AU_IOPENDING:
        default:
            Sleep(10);
            continue;
        };

        Sleep(10);
    };

    return 0;
}
void CPipeServer::OnEvent(int nEventID)
{
    switch(nEventID)
    {
    case AU_THRD_RUN:
        LOG << "Thread running" << std::endl;
        break;

    case AU_INIT:
        LOG << "Initializing pipe comm" << std::endl;
        break;

    case AU_SERV_RUN:
        LOG << "Pipe server running" << std::endl;
        break;

    case AU_CLNT_WAIT:
        LOG << "Waiting for client" << std::endl;
        break;

    case AU_CLNT_CONN:
        {
        std::wstring sData(_T("W\x03B5lc\x03c6me pipe client!"));
        SetData(sData);
        SetEvent(AU_IOWRITE);
        break;
        }

    case AU_READ:
        {
        std::wstring sData;
        GetData(sData);
        LOG << "Message from client: " << sData << std::endl;

        if(wcscmp(sData.c_str(), _T("cl\x03c6se")) == 0)
            SetEvent(AU_CLOSE);
        else
            SetEvent(AU_IOREAD);
        break;
        }
    case AU_WRITE:
        LOG << "Wrote data to pipe" << std::endl;
        SetEvent(AU_IOREAD);
        break;

    case AU_ERROR:
        LOG << "ERROR: Pipe error" << std::endl;
        SetEvent(AU_ERROR);
        break;

    case AU_CLOSE:
        LOG << "Closing pipe" << std::endl;
        SetEvent(AU_TERMINATE);
        break;
    };
}
void CPipeServer::WaitForClient()
{
    OnEvent(AU_CLNT_WAIT);
    if(FALSE == ConnectNamedPipe(m_hPipe, NULL)) 
    {
       
        OnEvent(AU_ERROR);
    }
    else
    {
        OnEvent(AU_CLNT_CONN);
    }
}

void CPipeServer::Close()
{
    ::CloseHandle(m_hPipe);
    m_hPipe = NULL;
}
bool CPipeServer::Read()
{
    DWORD drBytes = 0;
    BOOL bFinishedRead = FALSE;
    int read = 0;
    do
    {
        bFinishedRead = ::ReadFile( 
            m_hPipe,            
            &m_buffer[read],    
            AU_DATA_BUF,        
            &drBytes,           
            NULL);             

        if(!bFinishedRead && ERROR_MORE_DATA != GetLastError())
        {
            bFinishedRead = FALSE;
            break;
        }
        read += drBytes;

    }while(!bFinishedRead);

    if(FALSE == bFinishedRead || 0 == drBytes)
    {
        
        return false;
    }

    return true;
}
bool CPipeServer::Write()
{
    DWORD dwBytes;
    BOOL bResult = ::WriteFile(
        m_hPipe,                  
        m_buffer,              
        ::wcslen(m_buffer)*sizeof(wchar_t) + 1,   
        &dwBytes,            
        NULL);           

    if(FALSE == bResult || wcslen(m_buffer)*sizeof(wchar_t) + 1 != dwBytes)
    {
      
        return false;
    }

    return true;
}

CPipeServer::~CPipeServer(void)
{
	delete m_buffer;
    m_buffer = NULL;
}

Stefan_Lang

Вы не смогли предоставить определение класса сервера, всю клиентскую сторону, объяснение потока данных, который вы намереваетесь, и назначение m_buffer, то есть какие данные вы говорите, которые должны там храниться.

Кроме того, это раздел ответов _Quick_, и хотя он далек от завершения, объем кода, который вы опубликовали до сих пор, не позволяет быстро ответить просто из-за времени, которое потребуется для анализа этого кода.

Вы должны:
1. укажите, какие именно данные должны храниться в m_buffer
2. Укажите потока данных, который должен передать эту информацию от своего источника к классу PipeServer
3. Определите, какие функции вы можете использовать для достижения этого потока данных
4. Посмотрите документацию по функции
5. Используйте отладчик, чтобы убедиться, что каждый шаг в процессе передачи действительно делает то, что вы думали, что он должен.
6. если какой-либо из вышеперечисленных шагов приводит к проблемам, которые вы не можете решить самостоятельно, вернитесь, опишите шаги, которые Вы предприняли до этого момента достаточно подробно, и расскажите нам, в чем именно заключается ваша проблема.

Stefan_Lang

Вероятно, это не связано с проблемой, но вы используете calloc для выделения буфера, но удаляете, чтобы освободить его в деструкторе. Это вызовет (или фактически должно вызвать) исключение времени выполнения. Вы должны использовать соответствующую функцию release, в данном случае free().

Если бы вы использовали new[], правильным способом было бы вызвать delete [], чтобы указать, что вы освобождаете массив, а не один объект!

Richard MacCutchan

Хорошо подмечено. И ваш предыдущий комментарий заслужил 5 баллов.

Stefan_Lang

Спасибо Вам за этот виртуальный 5. Даже если это не влияет на мой профиль, приятно знать, что мой совет имеет смысл и ценится.

1 Ответов

Рейтинг:
1

Richard MacCutchan

Эта функция вызовет проблемы:

void CPipeServer::OnBuffer(wchar_t* m_bufferID)
{
    m_buffer = m_bufferID;
}

Вы перезаписываете указатель m_buffer, поэтому вы потеряете данные, которые были считаны в ранее выделенный буфер.


CPallini

Хорошо подмечено. Однако, если я не ошибаюсь, ОП его не использует.

Richard MacCutchan

Я понятия не имею, когда и даже используется ли эта функция. Но если нет, то почему он там?

CPallini

Хорошая мысль, действительно :-)

Stefan_Lang

Хороший улов, 5
Виноват он или нет, но это, по меньшей мере, очень подозрительно.