Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.144.41.252] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Приветствую
стоит задача - создать код, получающий информацию создал так: int nNetOpResult; // инициализировать WSA WSADATA wsaData; nNetOpResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if (NO_ERROR != nNetOpResult) return -1; // открыть сокет SOCKET pClientServerSocket = socket(AF_INET, SOCK_STREAM, 0); if (INVALID_SOCKET == pClientServerSocket) { // деинициализировать WSA WSACleanup(); return -1; } sockaddr_in pSocketAddress; pSocketAddress.sin_family = AF_INET; pSocketAddress.sin_addr.s_addr = inet_addr(strAddress); pSocketAddress.sin_port = htons(nPort); // соединиться по сокету nNetOpResult = connect(pClientServerSocket, (sockaddr*)&pSocketAddress, sizeof(pSocketAddress)); if (SOCKET_ERROR == nNetOpResult) { // закрыть сокет closesocket(pClientServerSocket); // деинициализировать WSA WSACleanup(); return -1; } while (::WaitForSingleObject(m_hClientServerEvent, 0) == WAIT_OBJECT_0) { char* pCBData = NULL; do { // получить размер буфера size_t szCBDataSize; if (recv(pClientServerSocket, (char*)&szCBDataSize, sizeof(szCBDataSize), 0) == SOCKET_ERROR) break; // выделить память под буфер pCBData = new char [szCBDataSize]; // получить непосредственно данные if (recv(pClientServerSocket, (char*)&nCBDataType, sizeof(nCBDataType), 0) == SOCKET_ERROR) break; // обработать данные // очистить память delete [] pCBData; pCBData = NULL; } while (false); // очистить память if (pCBData != NULL) delete [] pCBData; } // закрыть сокет closesocket(pClientServerSocket); // деинициализировать WSA WSACleanup(); Проверил - все работает, кроме функции recv, которая постоянно возвращает SOCKET_ERROR Я так понимаю это потому что, на другой стороне никто не работает, никто не шлет информацию Тогда пара вопросов: 1) чтобы постоянно не гонять цикл можно ли определить что соединение установлено 2) или в самой логике работы клиентского приложения есть ошибка? |
Сообщ.
#2
,
|
|
|
а что WSAGetLastError возвращает?
|
Сообщ.
#3
,
|
|
|
while (::WaitForSingleObject(m_hClientServerEvent, 0) == WAIT_OBJECT_0) { char* pCBData = NULL; do { // получить размер буфера size_t szCBDataSize; if (recv(pClientServerSocket, (char*)&szCBDataSize, sizeof(szCBDataSize), 0) == SOCKET_ERROR) break; // выделить память под буфер pCBData = new char [szCBDataSize]; // Непонятно это место: строкой выше память выделяется для одного буфера, а ниже чтение // выполняется в другой // получить непосредственно данные if (recv(pClientServerSocket, (char*)&nCBDataType, sizeof(nCBDataType), 0) == SOCKET_ERROR) break; // обработать данные // очистить память delete [] pCBData; pCBData = NULL; } while (false); // очистить память if (pCBData != NULL) delete [] pCBData; } |
Сообщ.
#4
,
|
|
|
dikdik, да это непонятно, но по идее не должно приводить к SOCKET_ERROR..
|
Сообщ.
#5
,
|
|
|
похоже у меня ошибка в логике работы
попробовал реализовать простой случай приложение является клиентом и сервером - и работает через адрес 127.0.0.1:1234 т.е. одна часть программы будет отсылать по этому адресу команды вторая часть - получать код выглядит так: class CNetEngine { protected: HANDLE m_hClientServerThread; HANDLE m_hClientServerEvent; SOCKET m_pServerClientSocket; protected: static DWORD WINAPI ClientServerThread(LPVOID pParams); DWORD _ClientServerThread(); public: CNetEngine(); ~CNetEngine(); void StartClientServer(); void StopClientServer(); int StartServerClient(); int StopServerClient(); }; // поток для обработки соединения клиент-сервер DWORD WINAPI CNetEngine::ClientServerThread(LPVOID pParams) { return ((CNetEngine*)pParams)->_ClientServerThread(); } DWORD CNetEngine::_ClientServerThread() { CDataStorage* pStorageData = CDataStorage::GetInstance(); char strServerAddress[64]; sprintf_s(strServerAddress, "%d.%d.%d.%d", pStorageData->m_pClientIP[0], pStorageData->m_pClientIP[1], pStorageData->m_pClientIP[2], pStorageData->m_pClientIP[3]); int nNetOpResult; // инициализировать WSA WSADATA wsaData; nNetOpResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if (NO_ERROR != nNetOpResult) return -1; // открыть сокет SOCKET pClientServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (INVALID_SOCKET == pClientServerSocket) { // деинициализировать WSA WSACleanup(); return -1; } // соединиться по сокету sockaddr_in pSocketAddress; pSocketAddress.sin_family = AF_INET; pSocketAddress.sin_addr.s_addr = inet_addr(strServerAddress); pSocketAddress.sin_port = htons(pStorageData->m_nClientPort); while (::WaitForSingleObject(m_hClientServerEvent, 0) == WAIT_OBJECT_0) { nNetOpResult = connect(pClientServerSocket, (sockaddr*)&pSocketAddress, sizeof(pSocketAddress)); ::Sleep(1000); } while (::WaitForSingleObject(m_hClientServerEvent, 0) == WAIT_OBJECT_0) { char* pCBData = NULL; do { // получить размер буфера size_t szCBDataSize; if (recv(pClientServerSocket, (char*)&szCBDataSize, sizeof(szCBDataSize), 0) == SOCKET_ERROR) { int nError = WSAGetLastError(); break; } // получить тип данных UINT nCBDataType; if (recv(pClientServerSocket, (char*)&nCBDataType, sizeof(nCBDataType), 0) == SOCKET_ERROR) break; // выделить память под буфер pCBData = new char [szCBDataSize]; // получить непосредственно данные if (recv(pClientServerSocket, (char*)&nCBDataType, sizeof(nCBDataType), 0) == SOCKET_ERROR) break; } while (false); // очистить память if (pCBData != NULL) delete [] pCBData; } // закрыть сокет closesocket(pClientServerSocket); // деинициализировать WSA WSACleanup(); return 0; } // запустить соединения клиент-сервер, сервер-клиент void CNetEngine::StartClientServer() { // запустить поток клиент-сервер m_hClientServerThread = ::CreateThread(NULL, 0, ClientServerThread, this, CREATE_SUSPENDED, NULL); m_hClientServerEvent = ::CreateEvent(NULL, TRUE, TRUE, _T("ClientServerEvent")); ::ResumeThread(m_hClientServerThread); } // остановить соединения клиент-сервер, сервер-клиент void CNetEngine::StopClientServer() { // остановить поток клиент-сервер ::CloseHandle(m_hClientServerEvent); if (::WaitForSingleObject(m_hClientServerThread, 2000) == WAIT_TIMEOUT) ::TerminateThread(m_hClientServerThread, 0); ::CloseHandle(m_hClientServerThread); m_hClientServerThread = NULL; m_hClientServerEvent = NULL; } // запустить поток сервер-клиент int CNetEngine::StartServerClient() { CDataStorage* pStorageData = CDataStorage::GetInstance(); char strServerAddress[64]; sprintf_s(strServerAddress, "%d.%d.%d.%d", pStorageData->m_pClientIP[0], pStorageData->m_pClientIP[1], pStorageData->m_pClientIP[2], pStorageData->m_pClientIP[3]); int nNetOpResult; // инициализировать WSA WSADATA wsaData; nNetOpResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if (NO_ERROR != nNetOpResult) return -1; // открыть сокет m_pServerClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (INVALID_SOCKET == m_pServerClientSocket) { // деинициализировать WSA WSACleanup(); return -1; } // соединиться по сокету sockaddr_in pSocketAddress; pSocketAddress.sin_family = AF_INET; pSocketAddress.sin_addr.s_addr = inet_addr(strServerAddress); pSocketAddress.sin_port = htons(pStorageData->m_nClientPort); nNetOpResult = bind(m_pServerClientSocket, (sockaddr*)&pSocketAddress, sizeof(pSocketAddress)); if (SOCKET_ERROR == nNetOpResult) { // закрыть сокет closesocket(m_pServerClientSocket); // деинициализировать WSA WSACleanup(); return -1; } nNetOpResult = listen(m_pServerClientSocket, SOMAXCONN); if (SOCKET_ERROR == nNetOpResult) { // закрыть сокет closesocket(m_pServerClientSocket); // деинициализировать WSA WSACleanup(); return -1; } return 0; } // остановить поток сервер-клиент int CNetEngine::StopServerClient() { // закрыть сокет closesocket(m_pServerClientSocket); // деинициализировать WSA WSACleanup(); return 0; } Запускаю StartClientServer и StartServerClient - и ничего не происходит - т.е. connect у клиента не происходит Мне кажется что у меня ошибка в общей логике работы приложения |
Сообщ.
#6
,
|
|
|
а где вызовы bind и accept?
|
Сообщ.
#7
,
|
|
|
CreateThread не есть гуд
|
Сообщ.
#8
,
|
|
|
Цитата =MOHAX= @ а где вызовы bind и accept? в функции CNetEngine::StartServerClient() Цитата Alca @ CreateThread не есть гуд а как еще - та часть которая должна получать сообщения должна в отдельном потоке крутиться, а как же иначе? |
Сообщ.
#9
,
|
|
|
_beginthreadex
|
Сообщ.
#10
,
|
|
|
Цитата Alca @ _beginthreadex Не замечал проблем при совместном использовании CreateThread и сокетов. Fireman, отладчиком пройдись и посмотри, встает ли сервер на accept(), одинаков ли порт и адресс у клиента и сервера, код ошибки(WSAGetLastError()). |
Сообщ.
#11
,
|
|
|
Цитата Не замечал проблем при совместном использовании CreateThread и сокетов А если CreateThread и CRT? |
Сообщ.
#12
,
|
|
|
у меня с CreateThread тоже проблем никогда не было
|
Сообщ.
#13
,
|
|
|
Вот я дурак - взялся за это _beginthreadex. Поставьте мне - 1.
|
Сообщ.
#14
,
|
|
|
инициализация серверной и клиентской части прошли без ошибок
на recv подвисла (так и должно быть поскольку recv ожидает или закрытия сокета или прихода пакета) но вот когда пытаюсь сделать send получаю ошибку 10057 - Socket is not connected. |
Сообщ.
#15
,
|
|
|
кстати,
m_hClientServerEvent = ::CreateEvent(NULL, TRUE, TRUE, _T("ClientServerEvent")); //случаем не бесконечный цикл то выходит? //Event всегда в сигнальном состоянии + создаеться с ManualReset, т.е чтобы сбросить, нужно вызвать ResetEvent(). while (::WaitForSingleObject(m_hClientServerEvent, 0) == WAIT_OBJECT_0) { nNetOpResult = connect(pClientServerSocket, (sockaddr*)&pSocketAddress, sizeof(pSocketAddress)); ::Sleep(1000); } |