1. to bernie: more on mixedlib.e and other stuff
- Posted by cense <cense at MAIL.RU> Nov 20, 2000
- 412 views
- Last edited Nov 21, 2000
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]
2. Re: to bernie: more on mixedlib.e and other stuff
- Posted by Bernie <xotron at PCOM.NET> Nov 21, 2000
- 430 views
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)
3. Re: to bernie: more on mixedlib.e and other stuff
- Posted by cense <cense at MAIL.RU> Nov 21, 2000
- 408 views
- Last edited Nov 22, 2000
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]
4. Re: to bernie: more on mixedlib.e and other stuff
- Posted by Bernie <xotron at PCOM.NET> Nov 22, 2000
- 392 views
>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
5. Re: to bernie: more on mixedlib.e and other stuff
- Posted by Bernie <xotron at PCOM.NET> Nov 22, 2000
- 424 views
>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