Re: Multithreaded server : Problem with WSAEventSelect
On 6 mar, 14:29, Ulrich Eckhardt <eckha...@satorlaser.com> wrote:
NaeiKinDus wrote:
I'm trying to code a webserver running under WinXP, multithreaded,
etc...
The creation of my threads, the handles, everything works fine except
this : the WSAEventSelect.
The first occurence of this function is in the main() and manages
connections. If a connection is accepted, it sends the newly created
socket to a thread that will handle both FD_WRITE and FD_READ...
Here's the prob : the second call to the WSAEventSelect fails and
returns WSAENOTSOCK...
You know what this means, right? It means the call was different to the
first call. However, it is hard to guess in what way it was different.
However, just one thing: it typically isn't beneficial to have a single
thread per connection. Rather, use one thread for several connections,
using the mentioned WSAEventSelect to poll all threads at once.
I'm not using one thread per connection. Actually 1 thread is supposed
to handle up to X connections (defined in a conf file). I used
WSAEventSelect 2 times : in the main() to handle connections and in
the thread func to handle both reading and writing cases.
I tried to send data thru that socket, and it worked...
What's the deal?
I tried the solution MSDN gave me, with WSAEventSelect(socket, NULL,
0); before setting the thing to FD_READ | FD_WRITE but it still won't
work...
Got an idea ?
Yep, provide some example code. There are way too many things one could do
wrong, in particular with threads, handles and low-level socket routines
that it is impossible to tell.
Uli
From the main, where sSock is the server's socket :
if (WSAEventSelect(sSock, sEvent, FD_ACCEPT) == SOCKET_ERROR)
{
cerr << "WSAEventSelect did not work for the following reason:
errcode" << WSAGetLastError() << endl;
closesocket(sSock);
WSACleanup();
WSACloseEvent(sEvent);
return INIT_FAILURE;
}
while (TRUE)
{
hEvent = WSAWaitForMultipleEvents(1, &sEvent, FALSE, WSA_INFINITE,
FALSE);
switch (hEvent)
{
// ... Creates the thread, then sends it the
client's socket
}
}
------------------------------------------------------------------------------------------------------------------------------------------------------------
The thread code :
while (TRUE)
{
if (TotalEvent)
{
hEvent = WSAWaitForMultipleEvents(TotalEvent, EventArray, FALSE,
WSA_INFINITE, FALSE);
switch (hEvent)
{
case WSA_WAIT_FAILED:
cerr << "In Thread /*/ WSAEventSelect: " << WSAGetLastError() <<
endl;
break;
default:
// Detects whether the FD_WRITE or FD_READ is invoked
}
}
if (PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_REMOVE))
if (msg.message == WM_USER)
{
clients[TotalEvent] = (SOCKET)msg.lParam;
//if (WSAEventSelect(clients[TotalEvent], EventArray[TotalEvent],
0) == SOCKET_ERROR) // Tried this from MSDN... Supposed to reset the
parameters used by a previous call to WSAEventSelect()
//{
// if (WSAGetLastError() == WSAENOTSOCK)
// cerr << "Not a socket !";
//}
if (WSAEventSelect(clients[TotalEvent], EventArray[TotalEvent],
FD_READ | FD_WRITE) == SOCKET_ERROR) // Ka-boom ! Here it blows up
{
cerr << "In Thread /*/ Socket Error ! Errcode: " <<
WSAGetLastError() << endl;
}
EventArray[TotalEvent] = WSACreateEvent();
TotalEvent++;
}
}