Слишком частое подключение к серверу C ++ из PHP приводит к исключению нарушения прав доступа

Итак, у меня есть сервер C ++, и в нем есть некоторые данные, к которым я хотел бы получить доступ из PHP.
Однако я должен быть в состоянии справиться с тем фактом, что многие люди могут подключиться к нему одновременно и залить сервер тоннами пакетов.

У меня просто есть PHP-скрипт, который открывает сокет, передает ему привет и закрывает сокет.
Если я обновляю страницу в браузере снова и снова, она затопляет сервер. Однако после отправки около 70-> 100 пакетов (подключение к сокету, отправка данных, закрытие сокета более 70 раз) я получаю исключение нарушения доступа:

Необработанное исключение в 0x010BC96D в Server.exe: 0xC0000005: расположение чтения нарушения доступа 0xFEEEFEEE.

Переменная дамп

Вот моя настройка соединения TCP:

double webListen = tcplisten(cst::WEB_PORT, 100, 1);

std::list<double> webUsers;

if (webListen <= 0) {
cout << "Failed to listen on port " << cst::WEB_PORT <<endl;
}
cout << endl << "Server listening on port " << cst::WEB_PORT << endl;
while(1){
//Sleep(5);
double WebUser = tcpaccept(webListen, 0);
if(WebUser > -1){
cout<< "NEW WEB SOCKET: " << WebUser <<  endl;
webUsers.push_back(WebUser);
}

std::list<double>::iterator it = webUsers.begin();
while (it != webUsers.end())
{

cout << "SOCK: " << *it << endl;
double Size = receivemessage(*it, 1024, 4);
if(Size == -1){

}
else if(Size == 0){
cout << "WEB SOCKET DISCONNECTED: " << *it << endl;
it = webUsers.erase(it);
}
else if(Size > 0){
cout << "SIZE: " << Size << endl;
//Not reading data until exception is fixed
}

}

}

(Я поставил 4 в аргументы для receivemessage (), потому что его
А вот моя функция receivemessage ():

int CSocket::receivemessage(int len, CBuffer*destination)
{
if(sockid<0)return -1;
int size = -1;
//std::vector<char> buff;
std::vector<char> *buff;
if(udp)
{
size = 8195;
//buff = new char[size];
buff = new std::vector<char>(size,'0');
size = recvfrom(sockid, &(*buff)[0], size, 0, (SOCKADDR *)&SenderAddr, &SenderAddrSize);
} else
{
if(format == 0 && !len)
{
unsigned short length;
if(recv(sockid, (char*)&length, 2, 0) == SOCKET_ERROR)return -1;
buff = new std::vector<char>(length,'0');
//buff = new char[length];
size = recv(sockid, &(*buff)[0], length, 0);
} else if(format == 1 && !len)
{
size = 65536;
buff = new std::vector<char>(size,'0');
//buff = new char[size];
size = receivetext(&(*buff)[0], size);
} else if(format == 2 || len > 0)
{
buff = new std::vector<char>(len,'0');
//buff = new char[len];
size = recv(sockid, &(*buff)[0], len, 0);
}
}
if(size > 0)
{
destination->clear();
destination->addBuffer(&(*buff)[0], size);
}
delete buff;
//if(buff != NULL)delete[] buff;
return size;
}

А также мой PHP-скрипт:

   <?php
require_once("../server_info.php"); //contains get_host() and get_port_web()
$waitTimeoutInSeconds = 1;
$errCode = 0;
$errStr = 0;

if(!($sock = socket_create(AF_INET, SOCK_STREAM, 0)))
{
$errorcode = socket_last_error();
$errormsg = socket_strerror($errorcode);

die("Couldn't create socket: [$errorcode] $errormsg \n");
}

echo "Socket created \n";

//Connect socket to remote server

if(!socket_connect($sock , get_host() , get_port_web()))
{
$errorcode = socket_last_error();
$errormsg = socket_strerror($errorcode);

die("Could not connect: [$errorcode] $errormsg \n");
}

echo "Connection established \n";

$message = "hello";

//Send the message to the server
if( ! socket_send ( $sock , $message , strlen($message) , 0))
{
$errorcode = socket_last_error();
$errormsg = socket_strerror($errorcode);

die("Could not send data: [$errorcode] $errormsg \n");
}

echo "Message sent successfully \n";

socket_close($sock);

?>

Я не уверен, почему после 70-100 розеток это исключение. У меня где-то есть утечка памяти? (возможно, в функции receivemessage ()?).

Иногда даже при более чем 34 сокетных соединениях он создает исключение.
Не уверен, что делать на этом этапе.

0

Решение

Вы не должны проверять указатель на NULL перед его удалением, язык гарантирует, что delete (NULL) ничего не сделает.
Кроме того, взгляните на свой код и посмотрите, действительно ли вам это нужно, чтобы он был указателем. Не было бы проще, если бы вы сделали это простым вектором?

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

Место чтения нарушения доступа 0xFEEEFEEE.

Если вы заглянете в окно Locals, то заметите, что «this» указывает на 0xFEEEFEEE, что является магическим числом в Windows: в отладочных сборках это значение присваивается свободному пространству кучи.
Таким образом, похоже, что в какой-то момент receivemessage () вызывается для удаленного объекта CSocket. Это та область, где я бы начал искать причину.

1

Другие решения

Кажется, что либо у tcpaccept (), либо receivemessage () возникла какая-то тупиковая ситуация, потому что они выполнялись в нескольких потоках и требовали одновременного доступа в какой-то момент.

Мое решение состояло в том, чтобы просто заблокировать взаимное исключение вокруг них обоих или просто оставить их всех в одном потоке.

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector