Я сделал серверное приложение для личного использования, но у меня всегда была проблема, когда клиент отключается. Я недавно понял, что это вызвано тем, что элемент, возвращенный функцией recv
не распознается правильно. Например:
char* mrecv(bool show, LPVOID pointerToObject) //Recieve a message
{
int iResult2 = recv(ClientSocket, recvbuf, 512, 0);
if (iResult2 > 0) {
if ((strncmp(recvbuf,"/",1)) != 0) {
printm(recvbuf, pointerToObject);
}
else if (iResult2 == 0) {
printf("Connection closing...\n");
closesocket(ClientSocket);
WSACleanup();
return "1";
}
else {
printm("recv failed with error: %d\n", WSAGetLastError());
printm("Client must have disconnected. Please select a new client.");
return "1";
}
return recvbuf;
}
Когда клиент отключается, функция возвращает "1" правильно родительской функции. Однако, когда я проверяю его так:
DWORD WINAPI recvfunc(LPVOID pointerToObject)
{
while (true) {
ClientSocket=client[currentclient].cs;
char* p = mrecv(true, pointerToObject);
std::cout<<p<<"\n";
if ( p == "1") {
client[currentclient].con=false;
ClientSocket=client[lastclient].cs;
return 1;
}
}
return 0;
}
оператор if
возвращает false, возвращает ли чек "1"
, но 1
печатает на экране безупречно.
Кто-нибудь знает, почему это происходит?
Я использую winsock, если вы этого не заметили.
Заранее спасибо :)
EDIT :: Все приведенные ниже ответы с этого редактирования кажутся одинаковыми, и все они решают проблему. Если вы посмотрите на первую функцию, указанную там, вы увидите, что я, по-видимому, даже столкнулся с этой проблемой раньше и должен был использовать это решение. Так что, похоже, мой мозг просто отбросил меня. В любом случае, спасибо за всю помощь. :)
Ваш mrecv
возвращает результат типа char*
.
Ваше сравнение:
if (mrecv(true, pointerToObject)=="1")
это сравнение указателей, а не сравнение строк. Это верно, только если оба экземпляра строки "1"
будут храниться по одному и тому же адресу.
Чтобы сравнить строки, используйте функцию strcmp
. Или, поскольку вы используете C++, подумайте о том, чтобы использовать класс std::string
(который имеет перегруженную функцию ==
которая выполняет сравнение строк) вместо использования исходных строк в стиле C.
Пытаться:
if (strcmp(mrecv(true, pointerToObject), "1") == 0)
Ваша проблема заключается в том, что вы не можете использовать оператор == таким образом со строками C-стиля (char arrays), потому что то, что сравнивается, это не содержимое строки, а значение указателя на первый символ, поскольку вы 'действительно сравнивает char * с char *. Если вы хотите сравнить фактическое значение, вам нужно разыменовать возвращаемый указатель, а также сравнить его с символьным значением вместо строкового литерала (одинарные кавычки вместо двойного):
if (*mrecv(true, pointerToObject) == '1') {
mrecv(true, pointerToObject)[0]
, вероятно, будет более читабельным и сделает более очевидным, что вы имеете дело с C-строкой
Вы возвращаете указатели на литералы только для чтения, эти адреса ненадежны для сравнения, как вы это делаете.
Вы можете пойти для сравнения строк, используя strcmp или любое другое сравнение строк C++
if ( strcmp(p,"1") == 0) { ...
Вы сравниваете указатели на символы, и нет гарантии, что один указатель будет равен другому:
Попробуй это:
if (mrecv(true, pointerToObject)[0] == '1')
Теперь вы сравниваете первый байт, возвращаемый mrecv
на символ 1
.
Тем не менее, я настоятельно рекомендую вам возвращать целые коды возврата, а не символы.