View previous topic :: View next topic |
Author |
Message |
bornsoft Contributor
Joined: 19 Feb 2009 Posts: 113 Location: Germany
|
Posted: Fri Jul 20, 2012 8:38 pm Post subject: C-Programmer's help needed ***SOLVED*** |
|
|
Hello guys,
quite silent here, I hope there is someone out there who can help me with my problem:
For my bsWinSock unit I'm working on, I need some help from someone who understands C-Language
to translate the four FD_SET macros defined in the WinSock headerfile winsock.h into VDS.
I'm planning to make my unit open source if everything is working.
It already works pretty good, except the "select" function, which the macros are needed for.
The macros I need to image in VDS are FD_ZERO(), FD_ISSET(), FD_SET() and FD_CLR().
Please help with the following and thanks a lot in advance.
bornSoft
The FD_SET Structure is:
Code: |
typedef struct fd_set {
u_int fd_count;
SOCKET fd_array[FD_SETSIZE];
} fd_set;
fd_count = The number of sockets in the set.
fd_array = An array of sockets that are in the set.
FD_SETSIZE = 64 (Defined in winsock.h)
|
The following is the macro code as defined in winsock.h
FD_ZERO() macro:
Code: |
#define FD_ZERO(set) (((fd_set *)(set))->fd_count=0)
|
FD_ISSET() macro:
Code: |
#define FD_ISSET(fd, set) __WSAFDIsSet((SOCKET)(fd), (fd_set *)(set))
|
FD_SET() macro:
Code: |
#define FD_SET(fd, set) do { \
if (((fd_set *)(set))->fd_count < FD_SETSIZE) \
((fd_set *)(set))->fd_array[((fd_set *)(set))->fd_count++]=(fd);\
}while (0)
|
FD_CLR() macro:
Code: |
#define FD_CLR(fd, set) do { u_int __i; \
for (__i = 0; __i < ((fd_set *)(set))->fd_count ; __i++) { \
if (((fd_set *)(set))->fd_array[__i] == fd) { \
while (__i < ((fd_set *)(set))->fd_count-1) { \
((fd_set *)(set))->fd_array[__i] = \
((fd_set *)(set))->fd_array[__i+1]; \
__i++; \
} \
((fd_set *)(set))->fd_count--; \
break; \
} \
} \
} while (0)
|
No idea why, but my feeling tells me that this line also could be of interest:
Code: |
extern int PASCAL __WSAFDIsSet(SOCKET, fd_set *);
|
The FD_CLR() macro looks the most complicated - but to me it's the least important one,
since the FD_SETs should be build new in any case before a new select call is made.
.
Last edited by bornsoft on Mon Jul 23, 2012 4:33 am; edited 1 time in total |
|
Back to top |
|
|
bornsoft Contributor
Joined: 19 Feb 2009 Posts: 113 Location: Germany
|
Posted: Sat Jul 21, 2012 12:16 am Post subject: |
|
|
To answer myself below is some code i found somewhere in the depths of the web that handles
the wanted macros. I don't know which programming language this is (Profan ???), but it looks
much easier to me than the C code above.
Greeting and waiting for some help
bornSoft
What I have until now is this:
Code: |
Create FD_SET structure
-----------------------
%%My_FD_SET = @bsWinSock(CREATE_FD_SET)
:CREATE_FD_SET
# typedef struct fd_set {
# u_int fd_count;
# SOCKET fd_array[FD_SETSIZE];
# } fd_set;
# struct fd_set
%%FD_SETSIZE = 64
%C = 1
repeat
%%fd_array = %%fd_array@binary(DWORD,0)
%C = @succ(%C)
until @greater(%C,%%FD_SETSIZE)
%%fd_count = @binary(DWORD,0)
%R = %%fd_count%%fd_array
exit %R
Or should I simply do This for an empty FD_SET ???
--------------------------------------------------
%%fd_count = @binary(DWORD,0)
exit %%fd_count
FD_ISSET macro
--------------
%R = @bsWinSock(FD_ISSET,%%Socket,%%My_FD_SET)
:FD_ISSET
# Macro FD_ISSET (Returns 0 or greater than 0)
%R = @LIB(ws2_32,__WSAFDIsSet,INT:,%2,@addr("%3"))
exit %R
|
I found out that "__WSAFDIsSet" is a function in WS2_32.DLL that is not documented in the Winsock documentation
and for compatibility to Berkley Sockets it schould not be used by a program directly. The original FD_ISSET() macro
uses this function itself. I do not need to run my code on Unix/BSD etc. so there shouldn't be a problem using this function. (?)
Here is what the "__WSAFDIsSet" function internally does:
Code: |
int FAR
__WSAFDIsSet(SOCKET fd, fd_set FAR *set)
{
int i = set->fd_count;
while (i--)
if (set->fd_array[i] == fd)
return 1;
return 0;
}
|
And here is the unknown (Profan?) code i found:
(It also uses the "__WSAFDIsSet" function)
Code: |
Proc FD_ZERO
Parameters fdset#
fdset#.fd_count& = 0
Endproc
---------------------------------------------------------------
Proc FD_ISSET
Parameters Socket&,fdset#
Return __WSAFDIsSet(Socket&,fdset#)
EndProc
---------------------------------------------------------------
Proc FD_SET
Parameters Socket&,fdset#
Declare i%
While i% < fdset#.fd_count&
Case Long(fdset#,4+i*4) = Socket&: Break
Inc i%
Wend
If fdset#.fd_count& = i%
If fdset#.fd_count& < %FD_SETSIZE
Long fdset#,4+i%*4 = Socket&
fdset#.fd_count& = fdset#.fd_count& + 1
EndIf
EndIf
EndProc
----------------------------------------------------------------
Proc FD_CLR
Parameters Socket&,fdset#
Declare i%
While i% < fdset#.fd_count&
If Long(fdset#.fd_array#,i%*4) = Socket&
While i% < (fdset.fd_count& - 1)
Long fdset#.fd_array#,i%*4 = Long(fdset#.fd_array#,(i+1)*4)
Inc i%
Wend
fdset.fd_count& = fdset.fd_count& - 1
Break
EndIf
Inc i%
Wend
EndProc
|
.
|
|
Back to top |
|
|
bornsoft Contributor
Joined: 19 Feb 2009 Posts: 113 Location: Germany
|
Posted: Sun Jul 22, 2012 3:29 am Post subject: |
|
|
To continue my self-discussion - here is an update:
I made some progress but there is still an issue with the FD_SET structure.
The SELECT function accepts my construction and gives no errors and even the
return value is correct but it doens't update the FD_SET struct. No idea why.
I attach a zip file containing a test project that should clarify my problem.
It is well documented and the WinSock helpfile is also included.
It would be very nice if an experianced programmer would have a look on it.
Thanks in Advance
bornSoft
Description: |
Test-Project Winsock.hlp is included |
|
Download |
Filename: |
Select_Test.zip |
Filesize: |
182.05 KB |
Downloaded: |
1147 Time(s) |
|
|
Back to top |
|
|
bornsoft Contributor
Joined: 19 Feb 2009 Posts: 113 Location: Germany
|
Posted: Mon Jul 23, 2012 4:40 am Post subject: |
|
|
Finally I got it working!
After a long, long time of head scratching I found the reason for the strange behaviour.
In VDS (maybe generally ?) local function variables have restrictions to share their contents,
so passing a value from a global variable to a local variable, then giving a pointer to a dll that
manipulates the content and reading it back from the local to a global variable does not
work. It could be done by something like RTLCopyMemory or RTLMoveMemory but this would make an
additional external function call nessesary for somthing that should be as simple as possible.
I came up with another solution: My selfmade FD_SET macros store the FD_SET struct in the
registry as a chain of four digit hex-numbers that can be easy converted to the binary
dword-array and can be accessed from inside and outside a function.
Another positive sideeffect is, that anytime the struct is accessed by one of my FD_SET macros,
it is automatically trimmed to the proper size as set in the fd_count field.
The Winsock select function does this not do any time. So the the way I'm doing it now makes the struct
reusable ... I could think of a kind of "realtime-socket-monitoring"
Anyway. The problem is solved, the night is over and I can go ahead with my WinSock unit.
Greetings and thanks for the discussion.
bornSoft
P.S. Wow - this is my 100th post !
.
|
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You can attach files in this forum You can download files in this forum
|
|