У меня много проблем с отслеживанием того, где я получаю BufferOverrun в приведенном ниже коде, когда отправляю данные сокета из моего клиента telnet flash / as3. В основном я ищу новые утечки памяти и тому подобное, поэтому в дополнение к этой проблеме, есть ли более простой способ проверки переполнения / переполнения буфера, чем ручная отладка?
/*
MTSocketServer
--------------
The purpose of this application is to have a client application that can connect to this server.
This server should be able to parse messages from connected users and to send them to other users.
*/
// Headers and Namespace
#include "stdafx.h"
#include "MTSocketServer.h"
using namespace std;
// Constants
#define BUFFERSIZE 1000
#define PORT 20248
// Global Variables
SOCKET server;
struct Client_Data
{
SOCKET client_socket;
string user_id;
};
list<Client_Data> clients;
// Method Prototypes
UINT Server_Thread(LPVOID pParams);
UINT Client_Thread(LPVOID pParams);
string Recv_String(SOCKET listener);
void Send_String(const char* message, SOCKET sender);
bool Identity_Exists(string id);
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
AfxBeginThread(Server_Thread, NULL);
while(_getch() != 27);
closesocket(server);
WSACleanup();
return 0;
}
UINT Server_Thread(LPVOID pParams)
{
// Spawn Server Thread
cout << "Main thread spawned, press ESC at any time to exit.\r\n";
WSADATA wsa_data;
SOCKADDR_IN server_location;
if (int wsa_return_val = WSAStartup(0x101, &wsa_data) != 0)
{
cout << "Incorrect version of 'Ws2_32.dll'.\r\n";
cout << "Client thread de-initialized.\r\n";
AfxEndThread(0, true);
return 1;
}
server_location.sin_family = AF_INET;
server_location.sin_addr.s_addr = INADDR_ANY;
server_location.sin_port = htons(20248);
server = socket(AF_INET, SOCK_STREAM, NULL);
if (server == INVALID_SOCKET)
{
cout << "Socket creation error.\r\n";
cout << "Client thread de-initialized.\r\n";
AfxEndThread(0, true);
return 1;
}
if (bind(server, (SOCKADDR*)&server_location, sizeof(server_location)) != 0)
{
cout << "Socket binding error.\r\n";
cout << "Client thread de-initialized.\r\n";
AfxEndThread(0, true);
return 1;
}
if (listen(server, 10) != 0)
{
cout << "Socket listening error.\r\n";
cout << "Client thread de-initialized.\r\n";
AfxEndThread(0, true);
return 1;
}
SOCKET client;
SOCKADDR_IN client_location;
int len_of_client = sizeof(client_location);
bool abort = false;
while(abort == false)
{
client = accept(server, (SOCKADDR*)&client_location, &len_of_client);
// Spawn Client Thread
cout << "Connection from " << inet_ntoa(client_location.sin_addr) << ". Client thread spawned.\r\n";
AfxBeginThread(Client_Thread, (LPVOID)client);
}
// De-Initialize Server Thread
cout << "Server thread de-initialized.\r\n";
AfxEndThread(0, true);
return 0;
}
UINT Client_Thread(LPVOID pParams)
{
SOCKET client = (SOCKET)pParams;
string client_id = "";
// Check if a client with the same ID is on already
send(client, "ID_ME", 6, 0);
client_id = Recv_String(client);
if (Identity_Exists(client_id))
{
Send_String("That ID is already taken. Please try another.", client);
} else
{
cout << "Created ID " << client_id << " successfully\r\n";
Send_String("Type 'send' to send a message, 'quit' to exit.", client);
Client_Data this_client;
this_client.user_id = client_id;
this_client.client_socket = client;
clients.push_back(this_client);
bool is_con = true;
while(is_con)
{
string response = Recv_String(client);
if (response == "send")
{
Send_String("What username to send to?", client);
string to_id = Recv_String(client);
if (Identity_Exists(to_id))
{
Send_String("Type your message below: ", client);
string temp = Recv_String(client) + "\n\0";
const char* message = temp.c_str();
for (list<Client_Data>::iterator iterator = clients.begin(), end = clients.end(); iterator != end; ++iterator)
{
if (to_id == iterator->user_id)
{
SOCKET temp = iterator->client_socket;
cout << temp;
Send_String(message, temp);
}
}
} else
{
Send_String("Invalid username specified", client);
}
}
else if (response == "quit")
{
Send_String("Quit Command Issued", client);
break;
}
else
{
Send_String("Invalid Command Issued", client);
}
}
}
// De-Initialize Client Thread
closesocket(client);
cout << "Client thread de-initialized.\r\n";
AfxEndThread(0, true);
return 0;
}
// Function to parse full string values since they are often recieved one at a time
string Recv_String(SOCKET listener)
{
char buffer[BUFFERSIZE];
string temp;
int numofbytes = 0;
while (true)
{
int num = recv(listener, buffer, BUFFERSIZE, 0);
numofbytes++;
buffer[num] = '\0';
if (buffer[num-1] == '\n')
break;
if(numofbytes >= BUFFERSIZE-1)
break;
temp += buffer;
strcpy(buffer, "");
}
return temp;
}
void Send_String(const char* message, SOCKET sender)
{
char buffer[BUFFERSIZE];
strcpy(buffer, message);
size_t size = strlen(message);
int sendtest = send(sender, buffer, size, 0);
strcpy(buffer, "");
}
bool Identity_Exists(string id)
{
for (list<Client_Data>::iterator iterator = clients.begin(), end = clients.end(); iterator != end; ++iterator)
{
if (id == iterator->user_id)
{
return true;
}
}
return false;
}