Как хранить данные в моей переменной 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. Даже если это не влияет на мой профиль, приятно знать, что мой совет имеет смысл и ценится.