I have been trying to code a multisocket client similar to MIRC...

I have been opening a bunch of sockets in a loop, and stowing the handles in an array, and calling WSAAsynchSelect for each socket, but with a unique WM_SOCKET value for each socket,
then I have been determining the socket# of a socket event by looking for uMsg>=WM_SOCKET and then subtracting WM_SOCKET from uMsg, and then retrieving the unique data for this socket from the array.
The array contains structures I defined , and includes the sockethandle, sin struct, and other unique data.

When I open a dozen or so sockets and start using them its fine but if I ask for 30 or more it becomes unstable.
Am I generating too many windowmessages?
Should I switch to BLOCKING and use Select and a FD_SET?
If so, how can I serve my application socketarray asynchronously
or rather how may I multiplex the socketarray in such a way as I am not having sockets idling while one is busy?
Posted on 2002-02-08 07:52:20 by Homer
It sounds like multithreading may be beneficial. You could just rely on FD_ACCEPT wParam for the socket connections and then fire up a new thread for each connection with your handler routines therein. Like a web server.
Posted on 2002-02-08 10:20:44 by rdaneel
Using many sockets that use many window messages can cause an instable program. Like already suggested by rdaneel, create a seperate thread for every connection. Have a look at WSAEventSelect, it can set an event object when a winsock event happens. You can use these to synchronize your threads.

Thomas
Posted on 2002-02-08 13:20:20 by Thomas
Thanks for the input guys,

I tried that once in the past, but I had the thread create a window//socket and so I had the same problem.
I'll look into that api function and see whats shaking :)
Posted on 2002-02-10 09:10:00 by Homer
Don't forget you have to use winsock 2 or higher to use the event functions (IIRC). Make sure you do the right WSAInit, this is one of those bugs that are pretty hard to find :)
Posted on 2002-02-10 09:25:59 by Qweerdy
I am using WSACreateEvent and WSAEventSelect for socketevent notification now, and I am calling WaitForSingleObject from my thread, thus it waits to connect... ok but how do I detect for all the other socketevents? Should I create separate event-objects fonr Connect,Read,Write and Close? Should I attempt to re-use my event-object for all four? If so should I use WSAWaitForMultipleEvents with my lone event-object? (cuz you can't use it to detect multiple socketevents on the same socket) and speaking of which I notice that WSANETWORKEVENTS is undefined in my masm includes.
Any thoughts or suggestions would be greatly appreciated.
Posted on 2002-02-12 06:31:16 by Homer
You can create 1 event object and select more than 1 FD_XXXX events you want notification for on that socket. if you want notification for another socket you need to create a seperate event object for it.

after the WSAWaitForMultipleEvents or WaitForSingleObject, call WSAEnumNetworkEvents on the socket to see what event actually occurred.

take a look at my (thread) code, the code was originally using 2 sockets but i modified it to 1 to suit your needs.



invoke WSACreateEvent
mov hEventRemote, eax
mov dword ptr [pEvents], eax

invoke WSAEventSelect, hRemoteSock, hEventRemote, FD_CLOSE+FD_READ ;we want notification for FD_CLOSE and FD_READ on hRemoteSock

@waitfornextevent:
invoke WSAWaitForMultipleEvents, 1, addr pEvents, FALSE, INFINITE, FALSE ;wait forever until one of the events (FD_CLOSE and FD_READ) occured on the event obj
;eax is now the index of the event object that got signaled, using only 1 event object here tho

invoke WSAEnumNetworkEvents, hRemoteSock, hEventRemote, addr wsaRemoteEvents ;check which events occured on the socket
test wsaRemoteEvents.lNetworkEvents, FD_READ ;was there a FD_READ event on the socket?
jz @f
;handle recv here
@@:
test wsaRemoteEvents.lNetworkEvents, FD_CLOSE ;was there a FD_CLOSE event on the socket?
jz @f
;handle close here
@@:
jmp @waitfornextevent:


hope it can help.
(ps: i'm not using any errorchecking here)

about the includes, get the new Masm package, it has the new includes by Thomas in windows.inc which are:
; ----------------------------------------

; aditional winsock equates and structure
; contributed by Thomas Bleeker.
; ----------------------------------------
FD_READ_BIT equ 0
FD_WRITE_BIT equ 1
FD_OOB_BIT equ 2
FD_ACCEPT_BIT equ 3
FD_CONNECT_BIT equ 4
FD_CLOSE_BIT equ 5
FD_QOS_BIT equ 6
FD_GROUP_QOS_BIT equ 7
FD_ROUTING_INTERFACE_CHANGE_BIT equ 8
FD_ADDRESS_LIST_CHANGE_BIT equ 9

FD_MAX_EVENTS equ 10
FD_ALL_EVENTS equ (1 SHL FD_MAX_EVENTS) - 1

WSANETWORKEVENTS STRUCT
lNetworkEvents dd ?
iErrorCode dd FD_MAX_EVENTS dup (?)
WSANETWORKEVENTS ENDS
Posted on 2002-02-12 08:09:18 by savage
Ok back again, I have now updated my MASM includes, and still I found WSA_WAIT_FAILED and WSA_WAIT_TIMEOUT were undefined ...
for anyone who cares, I found the winsock2.h include with all these nice winsock2 definitions at http://doc.ddart.net/msdn/header/include/winsock2.h.html

WSA_WAIT_FAILED equ -1
WSA_WAIT_TIMEOUT equ WAIT_TIMEOUT


Now I have the following question:
I am invoking WSAWaitForMultipleEvents, on a single Event Object, which has FD_CONNECT, FD_READ and FD_CLOSE selected. I check the returnvalue from this function.
Next I am invoking WSAEnumNetworkEvents, then I am fetching the event from the array @ wse.lNetworkEvents (where wse is a WSANETWORKEVENTS structure)
Ok I now check the value to be FD_CONNECT,FD_READ,FD_CLOSE or "something else"
and I find that occasionally this function returns the value 33.
WHY?

Also, often it returns 0, and rarely a couple of other values.
What the Hell?

Bemused....but not amused :confused:
Posted on 2002-02-14 23:12:39 by Homer
it probably has FD_READ+FD_CLOSE set which together is 33.

maybe you can post a small piece of your code, so we might be able to see what's happening
Posted on 2002-02-15 07:48:16 by savage
By George !! I do believe he's got it !!

Wonderful, I had used If/Else/Endif logic to check the Network State(s) , and a conventional thread loop (jumping back to an Event Wait function) and so my code had been detecting an inital READ (first data packet) but then I was getting a READ+CLOSE which I had not even been detecting for.
I will have some fun recoding the thread again heh.

As for posting my code, I believe if I posted it in its present form I would find this very topic closed by a moderator on account of the end to which I have devised this means, if you know what I means... anyone seriously interested in seeing some working and 100% MASM code for a multithreaded and multisocketed ClientSide application can yell out and I will post the source directly to them.
Personally I think it's irrelevant what KIND of network application I am coding, but it doesn't take much to wake the dogs around here, and they sleep so peacefully... :tongue:
Posted on 2002-02-16 08:00:22 by Homer