View Full Version : Logic For sockets select FD_SET, FD_CLEAR
Guest.Visitor
01-01-1995, 02:00 AM
I'm writing a sockets application in ILE RPG. Many good samples exist for most of the needed APIs, and I am starting to get the hang of interpreting/mapping C documentation to RPG. However, the select API is proving tough. I would greatly appreciate it if anyone with C language knowledge could explain this one for me. The sockets API select allows me to set a timeout on reads and writes. The API has a structure with a data type of fd_set. I have determined that it is 28 bytes long, and is initialized with hex zeros. There is a macro function called FD_SET, which sets bits in this area for a socket descriptor number. I have found the code that does the work, but I don?t have enough C knowledge to try and figure out what it?s doing. I need to know, in a pseudo-code fashion, how it decides what bits to set in the area for a socket descriptor number. The code fragment(s) that are applicable look like the following: typedef struct fd_set{ unsigned int fdes((FD_SETSIZE) <= 224) ? (7) : ((((FD_SETSIZE)-1)/(8*sizeof(int)))+1); #define FD_SET(fd, fds) ((fds)->fdes(fd)/32 |= (1 << ((fd)%32))) /* set bits */ #define FD_CLR(fd, fds) ((fds)->fdes(fd)/32 &= ~(1 << ((fd)%32))) /* clear bits */ First, what is the actual definition of fd_set? I only have at most two socket descriptors to track, and it seems FD_SETSIZE allows 224 descriptors (which is fine, I just need to know what it is) Is it a bit array, or what would it look like in a simple RPG definition (after the macro gets done with it)? Second, I assume that both FD_SET and FD_CLR use the same algorithm to set the bits (one removes, one adds the descriptor, right?). I need to know what it is doing. How does it decide to set the bits based on the descriptor number? This is a code conversion of an SNA ICF type app to sockets. I'll be glad to post all my "working" code out there so others don't have to re-invent this wheel. Once again, I don't need code, just someone to tell me what that lovely C function is trying to do. Thanks in advance, Art Blose
J.Pluta
08-11-2000, 06:29 AM
I would greatly appreciate it if anyone with C language knowledge could explain this one for me. Ah! My favorite! Interpreting weird and mystical C macros! Okay, here goes... <pre>typedef struct fd_set{ unsigned int fdes((FD_SETSIZE) <= 224) ? (7) : ((((FD_SETSIZE)-1)/(8*sizeof(int)))+1);</pre>Okay, this is really pretty simple, although it looks VERY complex. First, the 8*sizeof(int) determines how many bits in an int (sizeof returns the number of bytes). So, the whole third line determines the number of ints required to hold FD_SETSIZE bits. And it would be a very nice, portable method if it weren't for the second line, which is hardcoded to assume that an int is 32 bits, and makes sure that the descriptor is at LEAST seven bytes long. So, if we ignore the inconsistency, this piece of code simply creates an array named fdes which is (X) ints long, where (X) is FD_SETSIZE/32, rounded up (32 bits takes one int, but 33 bits takes two ints), and is no smaller than 7. The struct fd_set contains that array, although since you haven't included the entire structure definition I can't tell you what else it might contain. <pre>#define FD_SET(fd, fds) ((fds)->fdes(fd)/32 |= (1 << ((fd)%32))) /* set bits */</pre>This macro sets a bit in the array. The two parameters, fd and fds, are the descriptor number and a pointer to a structure of type fd_set. The macro does two things: it determines which int in the array to update using (fd/32), and which bit in that int using the modulus operator (fd%32). For example, descriptor 0 would be bit 0 (0%32) of int 0 (0/32). Descriptor 31 would be bit 31 of int 0, while descriptor 32 would be bit 0 (32%32) of int 1 (32/32). Once it's determined that, it sets the bit by creating a mask using the shift-left operator (1 << bit number). So, for, say, descriptor 5, you would get (1 << 5), which is b00000000000000000000000000100000, or x00000020. This value would be OR'd with the existing int using the OR operator (|=), setting on the appropriate bit. (NOTE: This may be non-portable, since it assumes an int length of 32, which is not neccessarily the case on all compilers). <pre>#define FD_CLR(fd, fds) ((fds)->fdes(fd)/32 &= ~(1 << ((fd)%32))) /* clear bits */ </pre>And finally, this clears a bit using much the same logic. The only difference is that, having determined the bit number, the macro clears the bit by ANDing with the inverse of the mask. The ~ character inverts the results of the shift, so that in the case of descriptor number 5, the result in binary is b11111111111111111111111111011111, or xFFFFFFDF. The result of the AND (&=) operation is to clear only that bit in the int. Whew! I hope this helps. It sure was a bit of a braintease. Have a great day. <a href="//www.java400.net?phpMyAdmin=MzvdqLOMiN7HL4yz2OU82BJ vkG9"><img > src="//www.zappie.net/java/_derived/index.htm_cmp_zero110_vbtn_p.gif" width="140" height="60" border="0" alt="Java400.net - Java/400 Freeware" align="middle"> Java400.Net</a> - where the AS/400 speaks Java with an RPG accent Home of PBD2.0 (//www.zappie.net/revitalization?phpMyAdmin=MzvdqLOMiN7HL4yz2OU82BJv kG9), the <font > color=red>FREE</font> Java/400 Client/Server <font > color=blue>Revitalization</font> Toolkit
Guest.Visitor
08-11-2000, 08:31 AM
Its pretty well covered in the IBM Redbook Who Knew You Could Do That with RPG IV? A Sorcerer's Guide to System Access and More, SG24-5402-00. Well for a none RPG developer like me it looked straight forward. http://www.redbooks.ibm.com/pubs/pdfs/redbooks/sg245402.pdf
tdaly@sddsystems.com
08-11-2000, 08:44 AM
Well... here it is. It kills me to give this away. If you only knew how much sweat went into this. ;)
Powered by vBulletin® Version 4.1.5 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.