Heya all - attached is an oop Class for a generic TCP/IP Server.
You can use it for anything you like :)
It will internally keep a database of up to 256 concurrent sessions PER SERVER OBJECT INSTANCE.
Just one small comment, the Server_StartListening proc will attempt to listen on the given port number, but failing that (if its in use), it will incrementally try the next port and the next until it finds one thats free. It will return the listening port number.
The Class assumes that your main program will take care of initiating and killing WinSock itself, but some error handling for major blunders is included.
Heres a basic WndProc to drive this class.
WndProc proc hWin :DWORD,uMsg :DWORD,wParam :DWORD, lParam :DWORD
local ErrBuf[256]:BYTE
.if uMsg==WM_CREATE
DisplayWindow hWin, SW_SHOW
.if pServer==NULL
mov pServer,new (Server)
.if eax==FALSE
invoke MessageBox,0,CTXT("failed to Create"),CTXT("kk"),MB_OK
.else
icall pServer, Server, StartListening, hWin, 1027
.if eax==FALSE
invoke MessageBox,0,CTXT("failed to Listen"),CTXT("kk"),MB_OK
.else
invoke wsprintf, addr ErrBuf, CTXT("Listening on Port %lu"),eax
invoke SetWindowText,hWin,addr ErrBuf
.endif
.endif
.endif
.elseif uMsg == WM_DESTROY ;User wants to quit
delete pServer
invoke PostQuitMessage,NULL
.elseif uMsg==WM_SOCKET
mov eax,lParam
and eax,0FFFFh
.if eax==FD_ACCEPT ;New Client Connection
icall pServer, Server, Accept
.elseif eax==FD_READ
icall pServer, Server, Read, wParam ;Client Sending Data to me
.elseif eax==FD_CLOSE
icall pServer, Server, Closed, wParam ;A socket has closed
.endif
.else
invoke DefWindowProc,hWin,uMsg,wParam,lParam
.endif
ret
WndProc endp
Enjoy :)
You can use it for anything you like :)
It will internally keep a database of up to 256 concurrent sessions PER SERVER OBJECT INSTANCE.
Just one small comment, the Server_StartListening proc will attempt to listen on the given port number, but failing that (if its in use), it will incrementally try the next port and the next until it finds one thats free. It will return the listening port number.
The Class assumes that your main program will take care of initiating and killing WinSock itself, but some error handling for major blunders is included.
Heres a basic WndProc to drive this class.
WndProc proc hWin :DWORD,uMsg :DWORD,wParam :DWORD, lParam :DWORD
local ErrBuf[256]:BYTE
.if uMsg==WM_CREATE
DisplayWindow hWin, SW_SHOW
.if pServer==NULL
mov pServer,new (Server)
.if eax==FALSE
invoke MessageBox,0,CTXT("failed to Create"),CTXT("kk"),MB_OK
.else
icall pServer, Server, StartListening, hWin, 1027
.if eax==FALSE
invoke MessageBox,0,CTXT("failed to Listen"),CTXT("kk"),MB_OK
.else
invoke wsprintf, addr ErrBuf, CTXT("Listening on Port %lu"),eax
invoke SetWindowText,hWin,addr ErrBuf
.endif
.endif
.endif
.elseif uMsg == WM_DESTROY ;User wants to quit
delete pServer
invoke PostQuitMessage,NULL
.elseif uMsg==WM_SOCKET
mov eax,lParam
and eax,0FFFFh
.if eax==FD_ACCEPT ;New Client Connection
icall pServer, Server, Accept
.elseif eax==FD_READ
icall pServer, Server, Read, wParam ;Client Sending Data to me
.elseif eax==FD_CLOSE
icall pServer, Server, Closed, wParam ;A socket has closed
.endif
.else
invoke DefWindowProc,hWin,uMsg,wParam,lParam
.endif
ret
WndProc endp
Enjoy :)
I just modified the Server Class - the Server_StartListening proc now has one more param, which is a pointer to your data processing callback function.
The callback procedure should contain two params, hSock and pData in that order, which are the handle of the socket that received the data, and a pointer to the data itself. You don't need to worry about resource allocations in your callback function, and the socket handle is there just if you decide to terminate the session from within the callback, or want to send replies...
The Class Support by Ultrano.
An example of a VERY simple callback data handler:
;================================================
ParseWebRequest proc hSock:DWORD, pData:DWORD
invoke MessageBox,0,pData,CTXT("Data"),MB_OK ;Do something with the data !!!!
ret
ParseWebRequest endp
;================================================
The callback procedure should contain two params, hSock and pData in that order, which are the handle of the socket that received the data, and a pointer to the data itself. You don't need to worry about resource allocations in your callback function, and the socket handle is there just if you decide to terminate the session from within the callback, or want to send replies...
The Class Support by Ultrano.
An example of a VERY simple callback data handler:
;================================================
ParseWebRequest proc hSock:DWORD, pData:DWORD
invoke MessageBox,0,pData,CTXT("Data"),MB_OK ;Do something with the data !!!!
ret
ParseWebRequest endp
;================================================
Now I've implemented a Client Class.
The Client Class objects only need to keep track of one socket handle (their own).
No need for the array resource like in the server class.
As a test, I created a Server object, told it to start listening, and then connected to localhost on the listening port using Client_Connect. Then I wait for the connect event before calling Client_Connected, where we send some data.
The server receives the data fine, loopback test was a success.
I was worried about making a second call to WSAASyncSelect with another socket and same window. I thought the Server might stop taking new clients. So after loopback I connected to the server using my browser, and it accepted me.
Everything's groovy.
If you wanna make multiple client connections, simply create multiple Client objects.
I'm not sure if I am closing the client sockets correctly, I forgot to check.
As you can see, this Client Class is a butchered version of the Server Class.
The Client Class objects only need to keep track of one socket handle (their own).
No need for the array resource like in the server class.
As a test, I created a Server object, told it to start listening, and then connected to localhost on the listening port using Client_Connect. Then I wait for the connect event before calling Client_Connected, where we send some data.
The server receives the data fine, loopback test was a success.
I was worried about making a second call to WSAASyncSelect with another socket and same window. I thought the Server might stop taking new clients. So after loopback I connected to the server using my browser, and it accepted me.
Everything's groovy.
If you wanna make multiple client connections, simply create multiple Client objects.
I'm not sure if I am closing the client sockets correctly, I forgot to check.
As you can see, this Client Class is a butchered version of the Server Class.
it's cool. i'll digest it. wanna learn some oop asm.