所以我有一个 C++ 服务器,其中有一些我想从 PHP 访问的数据。 然而,我需要能够处理这样一个事实,即许多人可能会同时连接到它,并用大量数据包淹没服务器。
我只有一个 PHP 脚本可以打开一个套接字,向它发送“hello”,然后关闭套接字。 如果我一遍又一遍地刷新浏览器上的页面,它就会淹没服务器。然而,在发送了大约 70->100 个数据包(连接到套接字、发送数据、关闭套接字超过 70 次)之后,我得到了一个访问冲突异常:
Unhandled exception at 0x010BC96D in Server.exe: 0xC0000005: Access violation reading location 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
}
}
}
(我在 receivemessage() 的参数中放了 4 因为它 这是我的 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 个套接字连接时它也会抛出异常。 不确定此时该做什么。
最佳答案
您不应该在删除指针之前测试它是否为 NULL,该语言保证 delete(NULL) 不会执行任何操作。 另外,看看你的代码,看看你是否真的需要它作为一个指针。如果把它做成一个简单的 vector 不是更容易吗?
回到你的崩溃,很可能它的原因不在你发布的代码段中。
Access violation reading location 0xFEEEFEEE.
如果您查看 Locals 窗口,您会注意到“this”指向 0xFEEEFEEE,这在 Windows 中是一个神奇的数字:在调试版本中,它是分配给释放的堆空间的值。 所以看起来在某个时候 receivemessage() 被调用到一个已删除的 CSocket 对象上。这是我要开始寻找原因的区域。
关于php - 从 PHP 连接到 C++ 服务器太多次导致访问冲突异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27615554/