flat assembler
Message board for the users of flat assembler.

Index > Windows > WinSock

Author
Thread Post new topic Reply to topic
FrozenKnight



Joined: 24 Jun 2005
Posts: 128
FrozenKnight 13 Jan 2006, 08:47
i'm begining to enter the workd of network apps. So studying winsock is only natural. but as i began to convert the C turts into ASM i began to take a look at the select() function. when i did i noticed the FD macros wern't included in the standard FASM macros. so i consulted my include files and found the code below. but i'm having troubble understanding it. in perticulat the FD_CLR macro can someone help me with this please.
Code:
/*
 * Basic system type definitions, taken from the BSD file sys/types.h.
 */
typedef unsigned char   u_char;
typedef unsigned short  u_short;
typedef unsigned int    u_int;
typedef unsigned long   u_long;

/*
 * The new type to be used in all
 * instances which refer to sockets.
 */
typedef u_int           SOCKET;

/*
 * Select uses arrays of SOCKETs.  These macros manipulate such
 * arrays.  FD_SETSIZE may be defined by the user before including
 * this file, but the default here should be >= 64.
 *
 * CAVEAT IMPLEMENTOR and USER: THESE MACROS AND TYPES MUST BE
 * INCLUDED IN WINSOCK.H EXACTLY AS SHOWN HERE.
 */
#ifndef FD_SETSIZE
#define FD_SETSIZE      64
#endif /* FD_SETSIZE */

typedef struct fd_set {
        u_int   fd_count;               /* how many are SET? */
        SOCKET  fd_array[FD_SETSIZE];   /* an array of SOCKETs */
} fd_set;

#ifdef __cplusplus
extern "C" {
#endif

extern int PASCAL FAR __WSAFDIsSet(SOCKET, fd_set FAR *);

#ifdef __cplusplus
}
#endif


#define FD_CLR(fd, set) do { \
    u_int __i; \
    for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count ; __i++) { \
        if (((fd_set FAR *)(set))->fd_array[__i] == fd) { \
            while (__i < ((fd_set FAR *)(set))->fd_count-1) { \
                ((fd_set FAR *)(set))->fd_array[__i] = \
                    ((fd_set FAR *)(set))->fd_array[__i+1]; \
                __i++; \
            } \
            ((fd_set FAR *)(set))->fd_count--; \
            break; \
        } \
    } \
} while(0)

#define FD_SET(fd, set) do { \
    if (((fd_set FAR *)(set))->fd_count < FD_SETSIZE) \
        ((fd_set FAR *)(set))->fd_array[((fd_set FAR *)(set))->fd_count++]=(fd);\
} while(0)

#define FD_ZERO(set) (((fd_set FAR *)(set))->fd_count=0)

#define FD_ISSET(fd, set) __WSAFDIsSet((SOCKET)(fd), (fd_set FAR *)(set))    
Post 13 Jan 2006, 08:47
View user's profile Send private message Reply with quote
vbVeryBeginner



Joined: 15 Aug 2004
Posts: 884
Location: \\world\asia\malaysia
vbVeryBeginner 13 Jan 2006, 09:34
you could check tomasz's Quetannon example which using winsock.

http://flatassembler.net/examples.php
Demonstration of using WinSock library to make TCP/IP connections.
Written by Tomasz Grysztar.
Post 13 Jan 2006, 09:34
View user's profile Send private message Visit poster's website Reply with quote
velox



Joined: 06 Jan 2006
Posts: 14
velox 13 Jan 2006, 21:31
FrozenKnight,

the FD_CLR(s,*set) removes a socket descriptor from the given fd_set structure.

i'll try to explain it with a little example. let's say we've connected to a
smtp server and we want to know if data can be read from "our"
smtp_socket.

first we set up a fd_set "structure" Wink

smtp_sock dd 0 ; here we put in the the connected socket

read_fds: ;read fd_set
socket_count dd 0 ;fd_count
socket_array dd FD_SETSIZE dup(0) ;fd_array

next, we should "set" our socket in the read_fds structure.
in C we could use FD_SET(smtp_sock,&read_fds)

in asm this translates into something like:

mov [socket_count],1 ; one socket (smtp_sock)
mov eax,[smtp_sock]
mov [socket_array],eax ; put it into structure

[the FD_CLR(smtp_sock,&read_fds) macro searches the socket_array for
smtp_sock,clears it from the array and decrements the fd_count value.]

next we call select:

xor ebx,ebx

push ebx ; optional pointer to a timeout structure
push ebx ;except_fds
push ebx ;write_fds

push read_fds

; we're only interested if we can read data
; write_fds and except_fds pointers are zeroed therefore

push ebx

call select

in our case eax should now be 1 if smtp_sock is ready for reading ....

i hope this snippet helped you. (at least a lil bit Wink )

regards,
velox
Post 13 Jan 2006, 21:31
View user's profile Send private message Reply with quote
FrozenKnight



Joined: 24 Jun 2005
Posts: 128
FrozenKnight 14 Jan 2006, 17:01
Yes, i think that does thank you.

While QnetAnon helps a little i dont think it's what i'm after. i'm trying to write a server which can accept over 1000 connections. and QnetAnon only supports one connection.
Post 14 Jan 2006, 17:01
View user's profile Send private message Reply with quote
okasvi



Joined: 18 Aug 2005
Posts: 382
Location: Finland
okasvi 15 Jan 2006, 03:48
have you read tutorial at www.madwizard.org ?



btw. i find it strange that last part of tutorial is
Quote:
12. Conclusion

Now you've seen both a blocking client and a blocking server. Blocking sockets are relatively easy to use because they fit in nicely in the program flow. Still, you've only seen pretty simple examples, since both the client and the server we showed did practically nothing with the data other than print it or in this case, encrypt and then send it back. It gets harder when we have to extract meaningful information from the received data like when dealing with a protocol like POP3. This is the point where most beginners get stuck. The next chapters will tell you more on how to deal with this.


maybe he didnt have time/skill to go further than that Laughing

_________________
When We Ride On Our Enemies
support reverse smileys |:
Post 15 Jan 2006, 03:48
View user's profile Send private message MSN Messenger Reply with quote
FrozenKnight



Joined: 24 Jun 2005
Posts: 128
FrozenKnight 15 Jan 2006, 11:01
First off i am learning from much more advanced documentation. Second I checked out that site earlyer. i'm not really intrested in blocking sockets becasue they dont support mupital connections very well if at all. Also i already know how to manage the efect that he mentione in his side note for the next turt.

the thing you need to remember when you look at that is that there are 2 types of data Variable length and Fixed length. Fixed length is easy because you can simply set up a struct for it and copy the data in as is. variable length is a little more complex becasue you have to either set a delimiter or know the length before you begin copying it. i personaly perfer the second method because it's a little faster but and doesn't require you to eliminate certan charicter sets from your strings.

I'm not a beginner programmer just begginging at sockets. give me a little credit. and i can convert between C and asm when i know what is going on (some code can be hard to understand even though it does something simple) which is why velox post was most helpfull.
Post 15 Jan 2006, 11:01
View user's profile Send private message Reply with quote
FrozenKnight



Joined: 24 Jun 2005
Posts: 128
FrozenKnight 17 Jan 2006, 09:32
just for anyone curious that wants to use the fd_set macro's in fasm. i created these functions (i updated them with macros to clean up code a bit but they basicaly act the same way.)

Code:
;fd_set macros
FD_SETSIZE = 64

struct fd_set
  fd_count      dd ?
  fd_array      dd FD_SETSIZE dup (?)
ends

;helper macros
macro FD_CLR fd, set
{ push  set
  push  fd
  call  pFD_CLR
}

macro FD_SET fd, set
{ push  set
  push  fd
  call  pFD_SET
}

macro FD_ZERO set
{ push  set
  call  pFD_ZERO
}

macro FD_ISSET fd, set
{ push  set
  push  fd
  call  pFD_ISSET
}

;fd_set functions
proc pFD_CLR  fd, set
  push  esi
  push  ecx
  push  ebx
  mov   ebx, [set]
  mov   esi, [fd]
  xor   ecx, ecx
 .oloop:
  cmp   ecx, [ebx+fd_set.fd_count]
  jge   .cleanup
  cmp   esi, [ebx+ecx*4+fd_set.fd_array]
  jz    .iloop
  inc   ecx
  jmp   .oloop
 .iloop:
  mov   eax, [ebx+ecx*4+fd_set.fd_array+4]
  mov   [ebx+ecx*4+fd_set.fd_array], eax
  inc   ecx
  cmp   ecx, [ebx+fd_set.fd_count]
  jl    .iloop
  dec   [ebx+fd_set.fd_count]
 .cleanup:
  pop   ebx
  pop   ecx
  pop   esi
  ret
endp

proc pFD_SET fd, set
  push  ebx
  mov   ebx, [set]
  mov   eax, [ebx+fd_set.fd_count]
  cmp   eax, FD_SETSIZE
  jge   .cleanup
  push  [fd]
  pop   [eax*4+ebx+fd_set.fd_array]
  inc   [ebx+fd_set.fd_count]
 .cleanup:
  pop   ebx
  ret
endp

proc pFD_ZERO set
  mov   eax, [set]
  mov   [eax+fd_set.fd_count], 0
  ret
endp

proc pFD_ISSET fd, set
  push  esi
  push  ecx
  push  ebx
  mov   ebx, [set]
  mov   esi, [fd]
  xor   ecx, ecx
  xor   eax, eax
 .oloop:
  cmp   ecx, [ebx+fd_set.fd_count]
  jge   .cleanup
  cmp   esi, [ebx+ecx*4+fd_set.fd_array]
  jz    .found
  inc   ecx
  jmp   .oloop
 .found:
  inc   eax
 .cleanup:
  pop   ebx
  pop   ecx
  pop   esi
  ret
endp    

i know i could probably have just created better macros but i'm not very familar with the macro system yet.
Post 17 Jan 2006, 09:32
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
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 cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.