Click to See Complete Forum and Search --> : Winsock and threads problem


verifier
March 6th, 2005, 06:31 AM
Can anyone tell me why I get Access Violation on:
SOCKET clientSocket = accept(server.m_listenSocket, (sockaddr*)&addr, &addrSize);
in MyThreadFunc?
Any suggestions how I can fix it?


#include "StdAfx.h"
#include ".\simpleserver.h"
#include <sstream>


SimpleServer::SimpleServer(void)
{
m_startupEvent = CreateEvent(0, TRUE, FALSE, 0);
WSAData data;
WSAStartup(MAKEWORD(2,2), &data);
}

SimpleServer::~SimpleServer(void)
{
WSACleanup();
}

SOCKET SimpleServer::CreateSocket()
{
return socket(AF_INET, SOCK_STREAM, 0);
}

void SimpleServer::LoadListenSocket()
{
m_listenSocket = CreateSocket();
if (m_listenSocket == INVALID_SOCKET)
{
throw StartError("Failed to create listen socket");
}

sockaddr_in service;
service.sin_family = AF_INET;
service.sin_addr.s_addr = m_listenAddress.empty() ? htonl(INADDR_ANY) : inet_addr(m_listenAddress.c_str());
service.sin_port = htons(m_listenPort);
if (bind( m_listenSocket, (SOCKADDR*) &service, sizeof(service)) == SOCKET_ERROR)
{
closesocket(m_listenSocket);
stringstream errMsg;
errMsg << "Failed to bin port " << m_listenPort << ", errorcode: " << GetLastError();
throw StartError(errMsg.str().c_str());
}

if (listen( m_listenSocket, 5 ) == SOCKET_ERROR)
{
closesocket(m_listenSocket);
stringstream errMsg;
errMsg << "Failed to listen on port " << m_listenPort << ", errorcode: " << GetLastError();
throw StartError(errMsg.str().c_str());
}
}

void SimpleServer::Start(int port, const string& specificAddress)
{
m_listenPort = port;
m_listenAddress = specificAddress;
LoadListenSocket();

DWORD threadId;
CreateThread(NULL, 0, MyThreadFunc, this, 0, &threadId);
WaitForSingleObject(m_startupEvent, 5000);
}

SimpleServerClient* SimpleServer::CreateClient()
{
return new SimpleServerClient;
}

void SimpleServer::Shutdown()
{
dtLock clientLock(m_critClients);
list<SimpleServerClient*>::iterator it = m_clients.begin();
for (; it != m_clients.end(); ++it)
{
(*it)->Disconnect();
m_clients.erase(it);
delete *it;
}
}

DWORD SimpleServer::MyThreadFunc(void* ptr)
{
SimpleServer& server = *(SimpleServer*)ptr;
SetEvent(server.m_startupEvent);

sockaddr_in addr;
int addrSize = sizeof(sockaddr_in);
while (true)
{
SOCKET clientSocket = accept(server.m_listenSocket, (sockaddr*)&addr, &addrSize);
if (clientSocket == INVALID_SOCKET)
{
cout << "Error " << WSAGetLastError() << " occurred." << endl;
return 0;
}
cout << "Accepted a connection from " << inet_ntoa(addr.sin_addr) << endl;

SimpleServerClient* clientPtr = server.CreateClient();
clientPtr->AssignSocket(&server, clientSocket);
clientPtr->OnConnect(inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
clientPtr->ReadOperation();

server.m_critClients.Lock();
server.m_clients.push_back(clientPtr);
server.m_critClients.Unlock();
}
return 0;
}


void SimpleServer::DeleteClient(SimpleServerClient* ptr)
{
delete ptr;
}

kuphryn
March 6th, 2005, 12:21 PM
Revise LoadListenSocket() and have it return boolean. Make sure the listening socket is valid before you spawn the worker thread.

Kuphryn

verifier
March 6th, 2005, 03:49 PM
Revise LoadListenSocket() and have it return boolean. Make sure the listening socket is valid before you spawn the worker thread.

Kuphryn
Am I blind, or what's wrong with listen socket?

I know that I'm not catching the exceptions from it, but I have removed a lot of functions when trying to find why it fails.

kuphryn
March 6th, 2005, 05:10 PM
In this case, it could be invalid.

Kuphryn

verifier
March 7th, 2005, 01:10 AM
well I get a socket from it. What in it can be invalid?

abuaathiqa
March 16th, 2005, 10:36 PM
You change the address casting like this in your thread function and try

SimpleServer* server = (SimpleServer*)ptr;

SOCKET clientSocket = accept(server->m_listenSocket, (sockaddr*)&addr, &addrSize);


This will make the difference.