the James Ladd's FASt Server - Win32 Socket Library

Started by six_L, December 07, 2007, 03:49:49 AM

Previous topic - Next topic

six_L

there are two selection while using the Win32 Socket.
1. use the CreateIoCompletionPort
2. use the window message(WM_SOCKET,FD_READ,FD_WRITE...)
why's the IO mode faster than the WINMSG? 
regards

ecube

can you post him code please? i was ironically just looking for it link on site wasn't working.

six_L

maybe it's not his last version.
Quote.586
.model flat,stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\ws2_32.inc
include \masm32\include\wsock32.inc
include \masm32\include\masm32.inc

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\ws2_32.lib
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\mswsock.lib      ; winsock2 ms specific library.

include   \masm32\MACROS\MACROS.ASM
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   WSA_INVALID_EVENT      equ 00h
   WSA_FLAG_OVERLAPPED      equ 01h
   MSG_PARTIAL         equ 8000h
   SO_UPDATE_ACCEPT_CONTEXT   equ 700Bh
   WSAEVENT         typedef HANDLE
;-------------------------------------------------------
WSAOVERLAPPED struct
   Internal   DWORD ?
   InternalHigh   DWORD ?
   an_Offset   DWORD ?
   OffsetHigh   DWORD ?
   hEvent      WSAEVENT ?
WSAOVERLAPPED ends
;-------------------------------------------------------
PWSAOVERLAPPED typedef ptr WSAOVERLAPPED
;-------------------------------------------------------
WSABUF struct
   len DWORD ?
   buf PBYTE ?
WSABUF ends
;-------------------------------------------------------
PWSABUF typedef ptr WSABUF
;-------------------------------------------------------
XOVERLAPPED struct
   overlapped        WSAOVERLAPPED <>
   operation         DWORD ?
   accept_socket     HANDLE ?
   accept_buffer     BYTE[2048] dup (0)
   bytes             DWORD ?
   wsabuf            WSABUF <>
   wsabuf_count      DWORD ?
XOVERLAPPED ends
;-------------------------------------------------------
PXOVERLAPPED typedef ptr XOVERLAPPED
;-------------------------------------------------------
FASTSVR struct
   wsadata            WSADATA <>
   io_completion_port HANDLE ?
   listen_socket      SOCKET ?
   listen_sockaddr_in sockaddr_in <>
   acceptors          PXOVERLAPPED <>
   io_workers         HANDLE ?
   end_event          HANDLE ?
FASTSVR ends
;-------------------------------------------------------
PFASTSVR typedef ptr FASTSVR;
;-------------------------------------------------------
   OPERATION_ENDED     equ 1
   OPERATION_ACCEPTED  equ 2
   OPERATION_READ      equ 3
   OPERATION_WRITTEN   equ 4
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data
   g_error         DWORD 0
   error         PDWORD offset error
   server         PFASTSVR 0

   msg_main_create      db "main_create",13,10,0
   msg_main_cleanup   db "main_cleanup",13,10,0
   msg_main_run      db "main_run",13,10,0
   msg_ok         db "ok",13,10,0
   msg_error      db "error",13,10,0
   msg_zero      db "status - zero",13,10,0
   msg_non_zero      db "status - non-zero",13,10,0
   msg_here      db "here",13,10,0
   msg_waiting      db "waiting",13,10,0
   msg_accept_complete   db "accept complete",13,10,0
   msg_read_complete   db "read complete",13,10,0
   msg_write_complete   db "write complete",13,10,0
   msg_end         db "end",13,10,0
   msg_serious_error   db "serious error",13,10,0
   msg_dump      db "%s %i",13,10,0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
align 4
memory_clear proc uses edi lpMem:DWORD, numBytes:DWORD, bUserVal:BYTE
   mov edi,lpMem       ; Pointer to memory
   mov  dl,bUserVal    ; Value to initialize memory with
   xor  eax,eax

   .if dl != 0         ; Build dword
      mov  al,dl
      shl  eax,8
      mov  al,dl
      mov  cx,ax
      shl  eax,16
      mov  ax,cx
   .endif

   mov  ecx,numBytes   ; number of bytes to write
   push ecx
   shr  ecx,2          ; numbers of dwords to write
   rep  stosd
   pop  ecx
   and  ecx,3          ; number of remaining bytes to write
   rep  stosb

   xor  eax,eax
   ret
memory_clear endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
printf proc C, format, param:VARARG
   local buffer[2048]:byte
   local count:dword

   invoke wvsprintf, addr buffer, format, addr param
   invoke lstrlen, addr buffer
   mov ecx, eax
   invoke GetStdHandle, STD_OUTPUT_HANDLE
   mov edx, eax
   invoke WriteFile, edx, addr buffer, ecx, addr count, NULL
   mov eax, count
   ret
printf endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
align 4
main_run proc svr:PFASTSVR, err:PDWORD
   invoke StdOut, addr msg_main_run

   mov eax, svr
   invoke WaitForSingleObject, [eax].FASTSVR.end_event, INFINITE

   mov eax, svr
   ret
main_run endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
align 4
main_create_server proc err:PDWORD
   local svr:PFASTSVR

   invoke GetProcessHeap
   invoke HeapAlloc, eax, 08h, sizeof FASTSVR
   mov svr, eax
   invoke memory_clear, svr, sizeof FASTSVR, 0

   mov eax, svr
   ret
main_create_server endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
align 4
main_create_network proc svr:PFASTSVR, err:PDWORD
   mov eax, svr
   lea edx, [eax].FASTSVR.wsadata
   invoke WSAStartup, 0202h, edx
   cmp eax, 0
   jne main_create_network_exit
   mov eax, svr
main_create_network_exit:
        ret
main_create_network endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
align 4
main_create_listener proc svr:PFASTSVR, err:PDWORD
   local sock:SOCKET
   local sockaddrin:sockaddr_in

   invoke WSASocket, AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED
   cmp eax, NULL
   je main_create_listener_exit
   mov edx, svr
   mov [edx].FASTSVR.listen_socket, eax
   mov sock, eax

   mov ecx, [edx].FASTSVR.io_completion_port
   invoke CreateIoCompletionPort, eax, ecx, 0, 0
   cmp eax, NULL
   je main_create_listener_exit

   lea edx, sockaddrin
   invoke htons, 9999D
   mov [edx].sockaddr_in.sin_port, ax
   mov [edx].sockaddr_in.sin_family, AF_INET
   mov [edx].sockaddr_in.sin_addr.S_un.S_addr, INADDR_ANY
   invoke bind, sock, edx, sizeof sockaddr_in
   cmp eax, 0
   jne main_create_listener_exit

   invoke listen, sock, 127
   cmp eax, 0
   jne main_create_listener_exit
   mov eax, svr

main_create_listener_exit:
        ret
main_create_listener endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
align 4
main_create_overlapped proc svr:PFASTSVR, err:PDWORD
   local ovl:PXOVERLAPPED

   invoke GetProcessHeap
   invoke HeapAlloc, eax, 08h, sizeof XOVERLAPPED
   mov ovl, eax
   invoke memory_clear, ovl, sizeof XOVERLAPPED, 0

   mov eax, ovl
   ret
main_create_overlapped endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
align 4
main_initialise_acceptor proc svr:PFASTSVR, err:PDWORD, ovl:PXOVERLAPPED
   local sock:SOCKET
   local opt:CHAR

   invoke WSASocket, AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED
   cmp eax, NULL
   je main_initialise_acceptor_exit
   mov sock, eax

   mov opt, 0
   lea edx, opt
   invoke setsockopt, sock, IPPROTO_TCP, TCP_NODELAY, edx, 1
   cmp eax, 0
   jne main_initialise_acceptor_exit

   mov eax, ovl
   mov edx, sock
   mov [eax].XOVERLAPPED.accept_socket, edx

main_initialise_acceptor_exit:
        ret
main_initialise_acceptor endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
align 4
main_create_acceptors proc svr:PFASTSVR, err:PDWORD
   local acceptors:PXOVERLAPPED

   invoke main_create_overlapped, svr, err
   cmp eax, 0
   je main_create_acceptors_exit
   mov acceptors, eax
   mov [eax].XOVERLAPPED.operation, OPERATION_ACCEPTED

   mov edx, svr
   mov [edx].FASTSVR.acceptors, eax

   invoke main_initialise_acceptor, svr, err, acceptors

main_create_acceptors_exit:
        ret
main_create_acceptors endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
align 4
main_accept_acceptors proc svr:PFASTSVR, err:PDWORD
   local listen_socket:SOCKET
   local accept_socket:SOCKET
   local bytes:PDWORD
   local outbuf:PBYTE
   local overlapped:PXOVERLAPPED

   mov eax, svr
   mov edx, [eax].FASTSVR.listen_socket
   mov ecx, [eax].FASTSVR.acceptors
   mov listen_socket, edx
   mov overlapped, ecx
   mov edx, [ecx].XOVERLAPPED.accept_socket
   mov accept_socket, edx
   lea edx, [ecx].XOVERLAPPED.accept_buffer
   mov outbuf, edx
   lea edx, [ecx].XOVERLAPPED.bytes
   mov bytes, edx

   invoke memory_clear, outbuf, 2048, 0

   invoke AcceptEx, listen_socket, accept_socket, outbuf,\
         2048 - ((sizeof sockaddr_in + 16) * 2),\
         sizeof sockaddr_in + 16, sizeof sockaddr_in + 16,\
         bytes, overlapped

   cmp eax, 0
   jne main_accept_acceptors_exit

   invoke WSAGetLastError
   cmp eax, ERROR_IO_PENDING
   je main_accept_acceptors_exit
   invoke StdOut, addr msg_error
   xor eax, eax
   ret

main_accept_acceptors_exit:
        invoke StdOut, addr msg_ok
        mov eax, svr
        ret
main_accept_acceptors endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
align 4
main_create_events proc svr:PFASTSVR, err:PDWORD

   invoke CreateIoCompletionPort, INVALID_HANDLE_VALUE, 0, 0, 0
   mov edx, svr
   mov [edx].FASTSVR.io_completion_port, eax

   invoke CreateEvent, 0, TRUE, FALSE, 0
   mov edx, svr
   mov [edx].FASTSVR.end_event, eax

   ret
main_create_events endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
align 4
main_acquire_overlapped proc svr:PFASTSVR, sock:SOCKET, operation:DWORD
   local ovl:PXOVERLAPPED

   ; TODO. At some point there should be a pool of structures.
   ;
   invoke GetProcessHeap
   invoke HeapAlloc, eax, 08h, sizeof XOVERLAPPED
   mov ovl, eax
   mov ecx, sock
   mov edx, operation
   mov [eax].XOVERLAPPED.accept_socket, ecx
   mov [eax].XOVERLAPPED.operation, edx
   mov [eax].XOVERLAPPED.wsabuf_count, 1
   lea edx, [eax].XOVERLAPPED.wsabuf
   lea ecx, [eax].XOVERLAPPED.accept_buffer
   mov [edx].WSABUF.buf, ecx
   mov [edx].WSABUF.len, 2048

   mov eax, ovl
   ret
main_acquire_overlapped endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
align 4
main_release_overlapped proc svr:PFASTSVR, ovl:PXOVERLAPPED

   ; TODO. At some point there should be a pool of structures.
   ;
   invoke GetProcessHeap
   invoke HeapFree, eax, NULL, ovl
   xor eax, eax

   ret
main_release_overlapped endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
align 4
main_io_worker proc svr:PFASTSVR
   local compport:HANDLE
   local compkey:DWORD
   local bytes:DWORD
   local overlapped:PXOVERLAPPED
   local listen_socket:SOCKET
   local accept_socket:SOCKET
   local wsabuf:PWSABUF
   local count:DWORD
   local flags:DWORD
   local err:DWORD

   mov eax, svr
   mov edx, [eax].FASTSVR.io_completion_port
   mov ecx, [eax].FASTSVR.listen_socket
   mov compport, edx
   mov listen_socket, ecx

main_io_worker_loop:
        invoke StdOut, addr msg_waiting

        invoke GetQueuedCompletionStatus, compport, addr bytes,\
      addr compkey, addr overlapped, INFINITE
        cmp eax, 0
        jne non_zero

zero:
        cmp overlapped, 0
        jmp main_io_worker_loop_seriously_wrong

        ; todo: close the socket.
        jmp main_io_worker_loop

non_zero:
        cmp compkey, OPERATION_ENDED
        je main_io_worker_end

        mov eax, overlapped
        mov edx, [eax].XOVERLAPPED.operation
        cmp edx, OPERATION_ACCEPTED
        je main_io_worker_accepted
        cmp edx, OPERATION_READ
        je main_io_worker_read
        cmp edx, OPERATION_WRITTEN
        je main_io_worker_written

        jmp main_io_worker_loop

main_io_worker_accepted:
        invoke StdOut, addr msg_accept_complete

        mov eax, overlapped
        mov edx, [eax].XOVERLAPPED.accept_socket
        mov accept_socket, edx

        invoke CreateIoCompletionPort, accept_socket, compport, 0, 0
        cmp eax, NULL
        je main_io_worker_loop_seriously_wrong

        mov eax, bytes
        cmp eax, 0
        je main_io_worker_loop_seriously_wrong

        mov eax, overlapped
        lea edx, [eax].XOVERLAPPED.accept_buffer
        lea ecx, [eax].XOVERLAPPED.wsabuf
        mov [ecx].WSABUF.buf, edx
        mov eax, bytes
        mov [ecx].WSABUF.len, eax
        push ecx

        ; print what we just received. 1 character typically.
        ;
        invoke printf, addr msg_dump, edx, bytes, eax

        pop ecx
        mov edx, overlapped
        mov [ecx].WSABUF.len, 1
        mov eax, OPERATION_WRITTEN
        mov [edx].XOVERLAPPED.operation, eax

        invoke WSASend, accept_socket, ecx, 1, addr bytes, 0,edx, 0

        jmp main_io_worker_loop

main_io_worker_read:
        invoke StdOut, addr msg_read_complete
        jmp main_io_worker_loop

main_io_worker_written:
        invoke StdOut, addr msg_write_complete

        mov eax, overlapped
        lea edx, [eax].XOVERLAPPED.accept_buffer
        lea ecx, [eax].XOVERLAPPED.wsabuf
        mov [ecx].WSABUF.buf, edx
        mov eax, 1
        mov [ecx].WSABUF.len, eax
        push ecx

        ; print what we just received. 1 character typically.
        ;
        invoke printf, addr msg_dump, edx, bytes, eax

        pop ecx
        mov edx, overlapped
        mov [ecx].WSABUF.len, 1
        mov eax, OPERATION_READ
        mov [edx].XOVERLAPPED.operation, eax

        invoke WSARecv, accept_socket, ecx, 1, addr bytes, addr flags, edx, NULL

        jmp main_io_worker_loop

main_io_worker_loop_seriously_wrong:
        ; TODO: take action here.
        invoke StdOut, addr msg_serious_error
        je main_io_worker_end

main_io_worker_end:
        invoke StdOut, addr msg_end

main_io_worker_exit:
        ret
main_io_worker endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
align 4
main_create_io_workers proc svr:PFASTSVR, err:PDWORD
   local tid:DWORD

   invoke CreateThread, NULL, 0, addr main_io_worker, svr,NULL, addr tid
   mov edx, svr
   mov [edx].FASTSVR.io_workers, eax

   ret
main_create_io_workers endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
align 4
main_create proc err:PDWORD

   invoke StdOut, addr msg_main_create
   invoke main_create_server, err
   cmp eax, 0
   je main_create_exit
   mov server, eax

   invoke main_create_network, server, err
   cmp eax, 0
   je main_create_exit

   invoke main_create_events, server, err
   cmp eax, 0
   je main_create_exit

   invoke main_create_io_workers, server, err
   cmp eax, 0
   je main_create_exit

   invoke main_create_listener, server, err
   cmp eax, 0
   je main_create_exit

   invoke main_create_acceptors, server, err
   cmp eax, 0
   je main_create_exit

   invoke main_accept_acceptors, server, err
   cmp eax, 0
   je main_create_exit

main_create_exit:
        ret
main_create endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
align 4
main_cleanup_server proc svr:PFASTSVR, err:PDWORD
   invoke GetProcessHeap
   invoke HeapFree, eax, NULL, svr
   xor eax, eax
   ret
main_cleanup_server endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
align 4
main_cleanup_listener proc svr:PFASTSVR, err:PDWORD
   invoke closesocket, [svr].FASTSVR.listen_socket
   ret
main_cleanup_listener endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
align 4
main_cleanup_events proc svr:PFASTSVR, err:PDWORD
   invoke CloseHandle, [svr].FASTSVR.io_completion_port
   invoke CloseHandle, [svr].FASTSVR.end_event
   ret
main_cleanup_events endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
align 4
main_cleanup_network proc svr:PFASTSVR, err:PDWORD
   invoke WSACleanup
   mov eax, svr
   ret
main_cleanup_network endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
align 4
main_cleanup_acceptors proc svr:PFASTSVR, err:PDWORD
   local acceptors:PXOVERLAPPED

   mov eax, svr
   mov edx, [eax].FASTSVR.acceptors
   mov acceptors, edx
   invoke CloseHandle, [edx].XOVERLAPPED.accept_socket

   invoke GetProcessHeap
   invoke HeapFree, eax, NULL, acceptors

   mov eax, svr
   ret
main_cleanup_acceptors endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
align 4
main_cleanup_io_workers proc svr:PFASTSVR, err:PDWORD

   mov edx, svr
   invoke PostQueuedCompletionStatus, [edx].FASTSVR.io_completion_port, 0,
         OPERATION_ENDED, NULL

   mov edx, svr
   invoke CloseHandle, [edx].FASTSVR.io_workers

   ret
main_cleanup_io_workers endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
align 4
main_cleanup proc svr:PFASTSVR, err:PDWORD
   cmp svr, 0
   je main_cleanup_exit

   invoke StdOut, addr msg_main_cleanup
   invoke main_cleanup_acceptors, svr, err
   invoke main_cleanup_listener, svr, err
   invoke main_cleanup_io_workers, svr, err
   invoke main_cleanup_events, svr, err
   invoke main_cleanup_network, svr, err
   invoke main_cleanup_server, svr, err

main_cleanup_exit:
        ret
main_cleanup endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Executable program starting/entry point.
;
;    mov svr.FASTSVR.thing, 2
;    mov eax, svr.FASTSVR.thing
Start:
   invoke main_create, error
   cmp eax, 0
   je main_exit

   invoke main_run, server, error

main_exit:
        invoke main_cleanup, server, error
        invoke ExitProcess, eax
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

end Start
regards

ecube

alright thanks alot man :D tried to find answer to your question couldn't find it

ecube

his code isn't really working, accepts connections, sends one byte back then doesnt do anything after that, I finally got his site working download his package is bunch of subversion garbage with no sources no help...really confusing and frustration as iocp always been interest of mine, thanks for posting source though ill play with it somewhere.

six_L

hey,E^cube
his code is working.
that's a tutorial about IOCP. not real application.
you must write some client's code to test his server.
regards

ecube

i tried testing with putty as the client and it allows connections but dies after 9 connects and the issue with the data...

ecube

I still can't get this to work, forgive me for not understanding the code but is suppose to support multiple clients? testing the code it goes through it's messages but after it sends the data back it doesn't do anything...no more notifications that data has arrived just hangs at         

invoke GetQueuedCompletionStatus, compport, addr bytes,\
      addr compkey, addr overlapped, INFINITE

and I can connect with other clients but when I send data the server doesnt do anything and overtime the clients just timeout and disconnect. can anyone read his latest snapshot? I tried using tortoise and it couldn't read it. looking at it normally didn't see anything but empty folders and a license file

ecube

im making good progress on fixing james code, what I fixed so far is added WSAIoctl call since apparently you can't call acceptex directly without linking to a special lib so that initializes it. he was using local variables on wsarecv and wsasend so I was getting Operation not supported (10054) so I changed them to structure variables(since if it could cause serious issues later even if it worked), he had a cmp overlapped, 0 and a jmp instead of je. I'm not sure if James has fixed all this as I haven't been able to look at the latest source, but is interesting code none the less :D

James Ladd

E^Cube,

Thank you for your message and for your interest in FASTserver.

As six_l points out that particular code snippet is an example / tutorial on what is involved in using IOCP with Win32.
It only accepts one connection at present, because the focus was on the IOCP API and not threading.

I did start working on a 'framework' that incorporated the IOCP stuff, so others could just write a DLL and not
worry about all the other stuff. However, this didn't go far, as I got busy on a lot of other things.

I'd be *very* interested in doing a project with you and others, to make a finished server with IOCP.
My only requirement would be that we don't just focus on Win32 but Linux as well.
This isn't as hard as you might think so don't let the multi-platform requirement put you off.

If your interested in doing this and with me leading the project then get in touch with me here or in
my blog.  I'll also post about some great books to read on the subject in my blog shortly.

Keep well,

Rgs, James.

ecube

Hi James yeah i'm interested to further your project and I have some linux programming experience, is there anyway you can post your latest code/framework somewhere?

James Ladd

Attached is the code that I started for the combined projects I had for Win32 and Linux.

There IS NO networking code in this ZIP, just framework stuff for writing assembler that would work on both
Linux and Windows (using cygwin).

The first set of routines I was going to implement were some non-blocking queues since these would
underpin all the other operations, like accepting connections and dealing with IO events. You can see a
start to these in the libjlc files.

The goal of these files is to have one set of source and a server for both platforms. However, this could be
too ambitious and I could be persuaded to focus on just one platform. Which platform would take a lot
more persuasion.

I will look over the backups I have and see if there is are some files for the server stuff. Stay Tuned.

Rgs, James.


[attachment deleted by admin]

James Ladd

Actually on second thought, it would be easier and quicker to just create a server in MASM for Win32. If it is popular then it can be ported to Linux.
No need to get all fancy and make it cross platform from the start.

Who wants to be involved?

ecube

Yeah I think you should start small then it can be expanded from there a server in masm using iocp with thread pooling is a very important piece of code that should be the standard for any and all servers written in masm/other languages for win2k+. I definitely am going to attempt to work with you/by myself to work out the kinks and add thread pooling to the  more recent code of yours from 2005, Mark Jones he was kind enough to upload to megashares which is 24/7 free file host. Are you ok with me posting here? i'm waiting for his approval aswell.

six_L

none is interesting at my question.
Quote
Thomas said:

1. Blocking sockets are probably the slowest. If you use pure blocking sockets, you will need a thread per socket (or two if sending and receiving is not done in turns like most protocols do). With high server load, you will quickly run out of resources (threads aren't lightweight resources Smile ).
An IO completion port is an advanced, very efficient and scalable way to automatically create a worker thread queue. The threads still block (you can send custom messages if necessary to interrupt the blocking), but they just wait for something to do, not for the operation to complete. That way they will never block (long) if there's enough to do which is very efficient.

2. Window messages are quite poor too, but it is more flexible than blocking since you don't loose control because of the blocking. Messages are slow so it isn't much of a strategy for high performance servers. Personally I don't really like using window messages for anything non-GUI related.

3. Events are pretty efficient, they are a much faster notification method than messages. There are two basic ways to use them: overlapped or not. Non-overlapped will work like WSAAsyncSelect (ie. notifications on network events), overlapped mode will use the event to signal operation completion. Overlapped is probably faster because it doesn't require calling send/recv again if it failed the first time.
Still one thread might not work very well, since you can only wait for 64 objects at a time (windows limitation). So if you need more connections you need more threads. IO completion ports don't need this and can easily support thousands of connections with just two threads (usually 1 or 2 thread per CPU). You do need to take care of the administration since you will loose the thread-connection relation that way.

[/b]
regards