私はTCPを使ってネットで動作するツールの開発を開始します。これはウェブサーバの簡単な機能を提供します。メモリ/スレッドリークWinSock2で簡単なHTTPサーバを開発する
私は非常に悪いミスを持っている私のプログラムをテストするには:
- メモリは、あなたがの1,5〜についてが表示されることがあり Taskmgr.exeので
- すぐスレッドの数千を作成
をリークスレッドと約50kbの割り当てられたメモリがあります。 また、プログラムを32ビットとしてコンパイルしましたが、vmmapユーティリティでは64ビットのスタックが多数表示されることがあります。私のOSは64ビットですが、taskmgr.exeでは* 32が表示されますが、32ビットプログラムが64ビットスタックをどのように使用しているかはわかりませんが、64ビットOSで32ビットプログラムを起動するのは普通ですが、あなたが私にこの質問についてのアドバイスをくれれば、私は非常に満足しています。
なぜ、私のプログラムはすぐに多くのスレッドを作成しましたか? (間違いなく、while(真)ブロックの原因)
しかし、私は次をしたい:
- リクエストが処理された場合には、それぞれの新しい要求
- ため、各スレッドを作成し、その後、スレッドと自由にメモリを終了
どのようにすべきです私のコードをリメイクしますか?
ありがとうございました!ここで
は私のコード(MS VC++ 9)である:
#include <iostream>
#include <Windows.h>
#pragma comment(lib, "Ws2_32.lib")
typedef struct Header
{
friend struct Net;
private:
WORD wsa_version;
WSAData wsa_data;
SOCKET sock;
SOCKADDR_IN service;
char *ip;
unsigned short port;
public:
Header(void)
{
wsa_version = 0x202;
ip = "0x7f.0.0.1";
port = 0x51;
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr(ip);
service.sin_port = htons(port);
}
} Header;
typedef struct Net
{
private:
int result;
HANDLE thrd;
DWORD exit_code;
void WSAInit(WSAData *data, WORD *wsa_version)
{
result = WSAStartup(*wsa_version, &(*data));
if(result != NO_ERROR)
{
std::cout << "WSAStartup() failed with the error: " << result << std::endl;
}
else
{
std::cout << (*data).szDescription << " " << (*data).szSystemStatus << std::endl;
}
}
void SocketInit(SOCKET *my_socket)
{
(*my_socket) = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if((*my_socket) == INVALID_SOCKET)
{
std::cout << "Socket initialization failed with the error: " << WSAGetLastError() << std::endl;
WSACleanup();
}
else
{
std::cout << "Socket initialization successful!" << std::endl;
}
}
void SocketBind(SOCKET *my_socket, SOCKADDR_IN *service)
{
result = bind((*my_socket), (SOCKADDR*)&(*service), sizeof(*service));
if(result == SOCKET_ERROR)
{
std::cout << "Socket binding failed with the error: " << WSAGetLastError() << std::endl;
closesocket((*my_socket));
WSACleanup();
}
else
{
std::cout << "Socket binding successful!" << std::endl;
}
result = listen(*my_socket, SOMAXCONN);
if(result == SOCKET_ERROR)
{
std::cout << "Socket listening failed with the error: " << WSAGetLastError() << std::endl;
}
else
{
std::cout << "Listening to the socket..." << std::endl;
}
}
static void SocketAccept(SOCKET *my_socket)
{
SOCKET sock_accept = accept((*my_socket), 0, 0);
if(sock_accept == INVALID_SOCKET)
{
std::cout << "Accept failed with the error: " << WSAGetLastError() << std::endl;
closesocket(*my_socket);
WSACleanup();
}
else
{
std::cout << "Client socket connected!" << std::endl;
}
char data[0x400];
int result = recv(sock_accept, data, sizeof(data), 0);
HandleRequest(data, result);
char *response = "HTTP/1.1 200 OK\r\nServer: Amegas.sys-IS/1.0\r\nContent-type: text/html\r\nSet-Cookie: ASD643DUQE7423HFDG; path=/\r\nCache-control: private\r\n\r\n<h1>Hello World!</h1>\r\n\r\n";
result = send(sock_accept, response, (int)strlen(response), 0);
if(result == SOCKET_ERROR)
{
std::cout << "Sending data via socket failed with the error: " << WSAGetLastError() << std::endl;
closesocket(sock_accept);
WSACleanup();
}
else
{
result = shutdown(sock_accept, 2);
}
}
static void HandleRequest(char response[], int length)
{
std::cout << std::endl;
for(int i = 0; i < length; i++)
{
std::cout << response[i];
}
std::cout << std::endl;
}
static DWORD WINAPI Threading(LPVOID lpParam)
{
SOCKET *my_socket = (SOCKET*)lpParam;
SocketAccept(my_socket);
return 0;
}
public:
Net(void)
{
Header *obj_h = new Header();
WSAInit(&obj_h->wsa_data, &obj_h->wsa_version);
SocketInit(&obj_h->sock);
SocketBind(&obj_h->sock, &obj_h->service);
while(true)
{
thrd = CreateThread(NULL, 0, &Net::Threading, &obj_h->sock, 0, NULL);
//if(GetExitCodeThread(thrd, &exit_code) != 0)
//{
// ExitThread(exit_code);
//}
}
delete &obj_h;
}
} Net;
int main(void)
{
Net *obj_net = new Net();
delete &obj_net;
return 0;
}
あなたは '* pointer-to-pointer *を削除してはいけません。' delete&obj_net'ではなく 'delete obj_net'を使用してください。 (あるいはboost :: scoped_ptrのようなスマートなポインタを使うのが良い) – Abyx
@Abyx:std :: unique_ptrのような標準のスマートポインタを使うのが良いです。 –
@RobertMason、VC++ 9には 'unique_ptr'はありません。 – Abyx