1. to bernie: more on mixedlib.e and other stuff

Hey there Bernie,

 I have more questions about mixedlib.e and the new "AssociatePtr( )" routine
you coded in responce to some of my earlier problems.

 I have wrapped the accept( ) function from C. This wrapper seems to work fine
on the surface eg. connections are accepted and i can send and recv through the
socket. The problem im having occurs randomly from the first to the ????
accept( ) attempt on a server using my wrapped accept( ). Mixedlib pops me
back with an error stating:

GETS FUNCTION FAILED !
Member sin_family does not exists

 Now i know that this *would* be normal if that member *did NOT* exist all the
time but this error randomly occurs. I use your "AssociatePtr( )" routine just
like you advised but it still messes up consistently but only after a
random number of connections.

 Here is the code i have so far for accept( ). I think that im also doing
someting wrong in initializing the sockaddr_in_ptr pointer.

-- include mixedlib.e

global
function accept( int sd )
  int status
  pointer sockaddr_in_ptr, len_ptr
  sequence return_seq
  
  sockaddr_in_ptr = allocate( 16 ) -- the size of a sockaddr_in struct
  len_ptr = get_pointer( sizeof( sockaddr_in_ptr ) )
  
  status = c_func( accept_, { sd, sockaddr_in_ptr, len_ptr } )
  
  if ( status > 0 and len_ptr != 0 ) then  
    AssociatePtr( sockaddr_in_ptr, get_sockaddr_in_seq( ), HIGH )
                        
    return_seq = { { Gets( sockaddr_in_ptr, "sin_family" ), -- error here
                     Gets( sockaddr_in_ptr, "sin_port" ),
                     Gets( sockaddr_in_ptr, "s_addr" ) }, status }
    
    free( len_ptr )
    free( sockaddr_in_ptr )
    return return_seq
  else
    free( len_ptr )
    free( sockaddr_in_ptr )
    return -1
  end if
  
end function

 get_sockaddr_in_seq( ) just returns a "struc" copatiable sequence.
I slightly modified AssociatePtr in how its invoked but not in its function.

 One other thing, the s_addr member of sockaddr_in_ptr always returns some
gooffy IP address and the last two dot delimited numbers (after conversion
using inet_ntoa) are always ?.?.17.8 no matter who connects, me or a friend.
I think this all has to do with the way that im initializing sockaddr_in_ptr
but ive tried many different ways and it never seems to make a difference.

 Any help on either of these two questions would greatly help. If you need
anymore info that i have not including i will be more than willing to mail it
away.

-- 
evil, corruption and bad taste
^[cense]

new topic     » topic index » view message » categorize

2. Re: to bernie: more on mixedlib.e and other stuff

cense:
  Warning I could not test this code.

  Because I don't know exactly how the rest of your program is coded
  If I understand what you are doing you don't need AssociatePtr
  I have tried to show you what to do in general.
  I hope this helps.
Bernie


-- include mixedlib.e

-- define the following structures outside of the function
-----------------------------------------------------------------
pointer generic_sockaddr
  generic_sockaddr =
  struc("sa_family_t:ushort:   1 "&      -- identifies format of address
data
 "sa_data    :  char: 256 ",HIGH) -- address buffer varies and can be
      -- greater than 14 bytes so use 256

-----------------------------------------------------------------
pointer addr_of_size_ptr -- upon RETURN contains (in bytes) address size
  addr_of_size_ptr = struc("length:int:1",HIGH)

-----------------------------------------------------------------

global -- assuming a socket has been established
function accept( int socket , pointer client, pointer client_length)
--
  int FD -- file_discriptor

  FD = c_func( accept_, { socket, client, client_length} )

  if FD < 0 then
    return -1 -- error condition
  else
    return FD -- return FILE DISCRIPTOR use for reading an writing/read
socket
  end if
--
end function

constant AF_INET = 2 --
pointer client1, client2
pointer client1_size_ptr1, client2_size_ptr1

  -- create the client structures
  client1 = dups(generic_sockaddr,HIGH) -- "C" socketaddr &client;
  client1_size_ptr = dups(addr_of_size_ptr,HIGH) -- "C" &client_length

  Sets(client1,"sa_family_t",AF_INET)   -- set the address family FORMAT
     -- so "C" knows what format to use
  int client1_FD
  -- get the file discriptor
  client1_FD = accept( socket, client1, client1_size_ptr)
  -- Now you can use the client1_FD to do read() or write()
  -- To the get the address of the client into a sequence do this:
  pointer client1_str_name
  sequence client1_seq_name

  -- allocate a string buffer
  client1_str_name = string(256)
  -- copy the address into the buffer this also gets rid of any garbage
  --   returned in the structure
  strncpy(client1_str_name, loc(client, "sa_data") , client1_size_ptr)
  -- You can use this string with any of the string functions in mixedlib.e
  -- or convert it to a sequence to use in Euphoria
  client1_seq_name = str2seq(client1_str_name)

  -- .... talk back and forth
  -- When you are DONE communicating with the client be sure to
  closeFD(client1_FD)
  free(client1)
  free(client1_size_ptr)
  free(client1_str_name)

new topic     » goto parent     » topic index » view message » categorize

3. Re: to bernie: more on mixedlib.e and other stuff

On Tue, 21 Nov 2000, Bernie wrote:
>> cense:
>>   Warning I could not test this code.
>> 
>>   Because I don't know exactly how the rest of your program is coded
>>   If I understand what you are doing you don't need AssociatePtr
>>   I have tried to show you what to do in general.
>>   I hope this helps.
>> Bernie

Well im still working on that socket wrapper for linux.  I have not worked on
it in a while and just discovered this during testing.

>> -- include mixedlib.e
>> 
>> -- define the following structures outside of the function
>> -----------------------------------------------------------------
>> pointer generic_sockaddr
>>   generic_sockaddr =
>>   struc("sa_family_t:ushort:   1 "&      -- identifies format of address
>> data
>>  "sa_data    :  char: 256 ",HIGH) -- address buffer varies and can be
>>       -- greater than 14 bytes so use 256
>> 
>> -----------------------------------------------------------------
>> pointer addr_of_size_ptr -- upon RETURN contains (in bytes) address size
>>   addr_of_size_ptr = struc("length:int:1",HIGH)
>> 
>> -----------------------------------------------------------------
>> 
>> global -- assuming a socket has been established
>> function accept( int socket , pointer client, pointer client_length)
>> --
>>   int FD -- file_discriptor
>> 
>>   FD = c_func( accept_, { socket, client, client_length} )
>> 
>>   if FD < 0 then
>>     return -1 -- error condition
>>   else
>>     return FD -- return FILE DISCRIPTOR use for reading an writing/read
>> socket
>>   end if
>> --
>> end function
>> 
>> constant AF_INET = 2 --
>> pointer client1, client2
>> pointer client1_size_ptr1, client2_size_ptr1
>> 
>>   -- create the client structures
>>   client1 = dups(generic_sockaddr,HIGH) -- "C" socketaddr &client;
>>   client1_size_ptr = dups(addr_of_size_ptr,HIGH) -- "C" &client_length
>> 
>>   Sets(client1,"sa_family_t",AF_INET)   -- set the address family FORMAT
>>      -- so "C" knows what format to use
>>   int client1_FD
>>   -- get the file discriptor
>>   client1_FD = accept( socket, client1, client1_size_ptr)
>>   -- Now you can use the client1_FD to do read() or write()
>>   -- To the get the address of the client into a sequence do this:
>>   pointer client1_str_name
>>   sequence client1_seq_name
>> 
>>   -- allocate a string buffer
>>   client1_str_name = string(256)
>>   -- copy the address into the buffer this also gets rid of any garbage
>>   --   returned in the structure
>>   strncpy(client1_str_name, loc(client, "sa_data") , client1_size_ptr)
>>   -- You can use this string with any of the string functions in mixedlib.e
>>   -- or convert it to a sequence to use in Euphoria
>>   client1_seq_name = str2seq(client1_str_name)
>> 
>>   -- .... talk back and forth
>>   -- When you are DONE communicating with the client be sure to
>>   closeFD(client1_FD)
>>   free(client1)
>>   free(client1_size_ptr)
>>   free(client1_str_name)

I understand all of your code above just fine. There is one thing that i need
clarrified though. When i look at online C socket tutorials for berkley sockets
i see the author always typecast a sockaddr_in structure to sockaddr and
then pass it to accept( ) instead of just using a sockaddr struct in the first
place 

What would be the use of this?

-- 
evil, corruption and bad taste
^[cense]

new topic     » goto parent     » topic index » view message » categorize

4. Re: to bernie: more on mixedlib.e and other stuff

>I understand all of your code above just fine. There is one thing that i
need
>clarrified though. When i look at online C socket tutorials for berkley
sockets
>i see the author always typecast a sockaddr_in structure to sockaddr and
>then pass it to accept( ) instead of just using a sockaddr struct in the
first
>place
>
>What would be the use of this?


 cense:

    I assume that this is what you are talking about.

     struct sockaddr_in client;
     int fd;
     client_len = sizeof(client);
     fd = accept(sock, (struct sockaddr *) &client, &client_len);


    The reason for this is that the real accept function prototype
    is:
     accept(int s, const void* addr, int addrlen)

    You will notice that the SECOND parameter is a VOID POINTER.
    A void pointer in "C" is a general type of pointer ( or holds a
    general address ) that can be assigned any type of pointer
    ( or address ). The void pointer can NOT be derefernced UNTIL
    it is FIRST CAST to ANOTHER type. SO because we are using the
    REFERENCE OPERATOR & ( or address operator ) we have to do a CAST
    to tell "C" to treat the VOID POINTER as a GENERIC SOCKADDR
    STRUCTURE POINTER. That means we can point to ANY SOCKADDR
    STRUCTURE TYPE. The sockaddr_in is only one of these types of
    structures.

    Hope that clears this up for you.

    Bernie



could benitialized
    to different

new topic     » goto parent     » topic index » view message » categorize

5. Re: to bernie: more on mixedlib.e and other stuff

>I understand all of your code above just fine. There is one thing that i
need
>clarrified though. When i look at online C socket tutorials for berkley
sockets
>i see the author always typecast a sockaddr_in structure to sockaddr and
>then pass it to accept( ) instead of just using a sockaddr struct in the
first
>place
>
>What would be the use of this?


 cense:

    I assume that this is what you are talking about.

     struct sockaddr_in client;
     int fd;
     client_len = sizeof(client);
     fd = accept(sock, (struct sockaddr *) &client, &client_len);


    The reason for this is that the real accept function prototype
    is:
     accept(int s, const void* addr, int addrlen)

    You will notice that the SECOND parameter is a VOID POINTER.
    A void pointer in "C" is a general type of pointer ( or holds a
    general address ) that can be assigned any type of pointer
    ( or address ). The void pointer can NOT be derefernced UNTIL
    it is FIRST CAST to ANOTHER type. SO because we are using the
    REFERENCE OPERATOR & ( or address operator ) we have to do a CAST
    to tell "C" to treat the VOID POINTER as a GENERIC SOCKADDR
    STRUCTURE POINTER. That means we can point to ANY SOCKADDR
    STRUCTURE TYPE. The sockaddr_in is only one of these types of
    structures.

    Hope that clears this up for you.

    Bernie

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu