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?
can you post him code please? i was ironically just looking for it link on site wasn't working.
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
alright thanks alot man :D tried to find answer to your question couldn't find it
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.
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.
i tried testing with putty as the client and it allows connections but dies after 9 connects and the issue with the data...
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
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
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.
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?
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]
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?
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.
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]
six_l
Im not sure what you mean by
Quotenone is interesting at my question.
However, here are some comments on making a server fast:
1. The fastest way to do anything is not to have to do it.
So don't block, don't context switch and don't consume more resources than you absolutely need to.
2. Synchronization hurts, so avoid it.
Try not to have points in your app that require you to wait, like a mutex or semaphore (locks).
Luckily we are using assembler and there are algos out there that use CPU atomic compare,
test and swap so you can do away with locks.
3. Look at the through put of the system and who needs to be responsive.
If you get a Windows event because some data has arrived, it may prove better to put this into a queue
for handling than try and handle it then and there, since you are starving the system of resources.
For example, with IO Completion, take the completion and put it onto your queue, releasing the
system resource.
4. You can make do with two threads per CPU but you should also have a few extras for house keeping.
For example, scavenging stale accept sockets etc.
5. Avoid copying data as much as possible.
You may be very surprised to find out how many times data is copied from buffer to buffer from the network card to your
program code.
6. The protocol you are implementing can also have a substantial impact on performance when
you measure through-put.
Detecting and setting packet sizes and other transmission characteristics will help.
Hello,James Ladd
as had seen your post, i'v got new knowledge.
pursuing the balance is better than pursuing the speed. this is the problem of local efficient and Global efficient.
Thank you very much.