forum.vdsworld.com Forum Index forum.vdsworld.com
Visit VDSWORLD.com
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


C-Programmer's help needed ***SOLVED***

 
Post new topic   Reply to topic    forum.vdsworld.com Forum Index -> General Help
View previous topic :: View next topic  
Author Message
bornsoft
Contributor
Contributor


Joined: 19 Feb 2009
Posts: 113
Location: Germany

PostPosted: Fri Jul 20, 2012 8:38 pm    Post subject: C-Programmer's help needed ***SOLVED*** Reply with quote

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
View user's profile Send private message Visit poster's website
bornsoft
Contributor
Contributor


Joined: 19 Feb 2009
Posts: 113
Location: Germany

PostPosted: Sat Jul 21, 2012 12:16 am    Post subject: Reply with quote

To answer myself Wink 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
View user's profile Send private message Visit poster's website
bornsoft
Contributor
Contributor


Joined: 19 Feb 2009
Posts: 113
Location: Germany

PostPosted: Sun Jul 22, 2012 3:29 am    Post subject: Reply with quote

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



Select_Test.zip
 Description:
Test-Project
Winsock.hlp is included

Download
 Filename:  Select_Test.zip
 Filesize:  182.05 KB
 Downloaded:  1140 Time(s)

Back to top
View user's profile Send private message Visit poster's website
bornsoft
Contributor
Contributor


Joined: 19 Feb 2009
Posts: 113
Location: Germany

PostPosted: Mon Jul 23, 2012 4:40 am    Post subject: Reply with quote

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" Wink

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
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    forum.vdsworld.com Forum Index -> General Help All times are GMT
Page 1 of 1

 
Jump to:  
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

Twitter@vdsworld       RSS

Powered by phpBB © 2001, 2005 phpBB Group