私は現在、私のコードで非常に奇妙な問題を抱えています。宣言後は問題ないように見える変数が、直後に破損し、アクセス違反が発生します (基本的に、ポインターはまだ同じ場所を指していますが、メモリは割り当てられていないようです)。問題がマルチスレッドに関連していると確信していますが、マルチスレッドにまったく慣れていないため、それが何であるかはわかりません。
コードは次のとおりです。
#include "Firewall.h"
#include <Ws2tcpip.h>
Firewall::Firewall(void)
{
}
Firewall::~Firewall(void)
{
}
void Firewall::parseFile(string filePath)
{
XMLNode xMainNode=XMLNode::openFileHelper(filePath.c_str(),"firewall");
// Filtrage
XMLNode nodeFiltrage = xMainNode.getChildNode("filtrage");
XMLNode currentNode;
for(int i=0; i < nodeFiltrage.nChildNode();i++)
{
currentNode = nodeFiltrage.getChildNode(i);
string nom = currentNode.getName();
if(nom == "permettre")
mapFiltrage_.insert(pair<int,bool>(atoi(currentNode.getAttribute().lpszValue), true));
else if(nom == "bloquer")
mapFiltrage_.insert(pair<int,bool>(atoi(currentNode.getAttribute().lpszValue), false));
}
// Redirection
XMLNode nodeRedirection = xMainNode.getChildNode("redirection");
XMLNode currentSubNode;
for(int i = 0; i < nodeRedirection.nChildNode(); i++)
{
currentNode = nodeRedirection.getChildNode(i);
currentSubNode = currentNode.getChildNode("source");
SourceDestination source((string)currentSubNode.getAttribute("adresse"), atoi(currentSubNode.getAttribute("port")));
currentSubNode = currentNode.getChildNode("destination");
SourceDestination destination((string)currentSubNode.getAttribute("adresse"), atoi(currentSubNode.getAttribute("port")));
mapRedirection_.insert(pair<SourceDestination, SourceDestination>(source,destination));
pair<SourceDestination, SourceDestination> test;
}
}
void Firewall::initialiser()
{
std::map<int, bool>::iterator iterFiltrage = mapFiltrage_.begin();
HANDLE handleThread;
std::string tempFiltrage = "localhost";
thread_arg arg;
// Parcours et lancement des connexions de filtrage
while(iterFiltrage != mapFiltrage_.end())
{
arg.port = (*iterFiltrage).first;
arg.host = tempFiltrage;
arg.objRef = this;
handleThread = CreateThread(NULL, 0, listenThread, &arg, 0, NULL);
listeThread_.push_back(handleThread);
iterFiltrage++;
}
// Parcours et lancement des connexions de redirection
std::map<SourceDestination, SourceDestination>::iterator iterRedirection = mapRedirection_.begin();
while(iterRedirection != mapRedirection_.end())
{
// Éviter la duplication inutile des sockets
if(mapFiltrage_.find((*iterRedirection).first.Port()) == mapFiltrage_.end())
{
arg.host = (*iterRedirection).first.Host();
arg.port = (*iterRedirection).first.Port();
arg.objRef = this;
handleThread = CreateThread(NULL, 0, listenThread, &arg, 0, NULL);
listeThread_.push_back(handleThread);
}
iterRedirection++;
}
}
DWORD WINAPI Firewall::listenThread(LPVOID lpParam)
{
thread_arg* temp = (thread_arg*)lpParam;
Firewall* firewallRef = temp->objRef;
return firewallRef->runThread(lpParam);
}
DWORD Firewall::runThread( LPVOID lpParam )
{
thread_arg* infosSocket = (thread_arg*)lpParam;
// Créer le socket et l'attacher à la source
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock == INVALID_SOCKET)
{
cout << "Erreur de creation de socket" << endl;
return EXIT_FAILURE;
}
//Recuperation de l'adresse locale
hostent *thisHost;
const char* test = infosSocket->host.c_str();
thisHost=gethostbyname(test);
char* ip;
ip=inet_ntoa(*(struct in_addr*) *thisHost->h_addr_list);
SOCKADDR_IN sin;
sin.sin_addr.s_addr = inet_addr(ip);
sin.sin_family = AF_INET;
sin.sin_port = htons(infosSocket->port);
if(bind(sock, (SOCKADDR*)&sin, sizeof(sin)) == SOCKET_ERROR)
{
cout << "Erreur de binding" << endl;
return EXIT_FAILURE;
}
// Contexte du client
SOCKADDR_IN csin;
SOCKET csock;
socklen_t crecsize = sizeof(csin);
listeSocket_.push_back(sock);
listeSocket_.push_back(csock);
// Écouter sur le port
if(listen(sock, 5) == SOCKET_ERROR)
{
cout << "Erreur de listen" << endl;
return EXIT_FAILURE;
}
//csock = accept(sock, (SOCKADDR*)&csin, &crecsize);
return EXIT_SUCCESS;
}
void Firewall::quitter()
{
// Fermer les sockets
vector<SOCKET>::iterator iter1 = listeSocket_.begin();
while(iter1 != listeSocket_.end())
{
closesocket((*iter1));
iter1++;
}
// Fermer les threads
vector<HANDLE>::iterator iter2 = listeThread_.begin();
while(iter2 != listeThread_.end())
{
TerminateThread((*iter2), EXIT_SUCCESS);
CloseHandle((*iter2));
}
}
どうもありがとう。