Hi,
Przemyslaw Czerpak wrote:
socket.c - alternative lightweight socket library, I do not like
hbinet.c a lot. If you want to compile it for Linux,
you'll need to adjust includes, but code should be
portable;
I ported it to Linux but it needs also some cleanup to remove MS-Windows
only code and fix some function parameters which are not POSIX compatible:
1. Here is the list of necessary header files:
...
8. The constant identifiers for shutdown() are different. Instead of SD_BOTH
SHUT_RDWR should be used.
With the above modifications it can be used with current Linux versions.
Thanks, for detailed modification lists. I just want to say, that I had
no intention to do this code 100% portable. I was not trying to publish
new socket library, it was just for helping compile uhttpd under
windows. Many modifications are known to me, but some are new.
Anyhow there are still some problems which can be exploited by upper level
.prg code because there are some small differences in socket functions
behavior on different platform:
1. Some functions which returns pointers to some structures/buffers may not
be MT safe on some platforms and usually are not. They should be replaced
by MT safe functions, f.e. inet_ntoa().
We can implement inet_ntoa() ourselves. I know some issues about
gethostbyname(). Do you know more winsock MT problems?
2. bind(), listen(), close(), shutdown() and some other functions changes
errno but may not change h_errno on some systems. This should be
respected by SOCKET_ERROR() function so we will have to store errors
after function call and probably bound them with socket or at least keep
them in thread local area to make error checking MT safe. Here we should
probably add error code translation.
I see no problem in having socket structure and related data (like error
code) in it.
I like the idea of giving as close as possible access to socket functions
at .prg level but we should also design a layer which will hide platform
differences. Each of use has own preferences from C programming. F.e.
I used to use read() and write() for connected sockets instead of recv()
send(). In general I used them just like any other descriptors for files,
pipes, character devices, ... also with select(). But it does not work in
MS-Windows and I have to accept it and change my preferences if I want
to create common for all platforms harbour interface.
Perhaps, read(), write() support is the thing we can not implement
(without our own file handler support under Harbour). winsock2 has new
"overlapped I/O" support, but WSASend(), WSARecv() is used instead of
standard ReadFile(), WriteFile().
1) strange, difficult to remember function names, ex., hb_InetPort()
returns port, but I can't remember local or remote. getpeername() is
more clear to me. hb_InetTimeout(), hb_InetTimelimit() - I do not know
that is we difference. hb_InetCount() - number of what? Internet
providers on my computer? I do not find bind() and listen() functions in
the list. hb_InetRecvEndBlock() - what kind of animal is it?
I only remember that one is inter recv()/send() delay and second is
used as total timeout limit for whole receive or send operation.
hb_inet*() functions try to complete this operation until given
stop condition (f.e. full buffer received or transmitted) so they
can repeat recv()/send() operations.
I've just check hbinet.c source code that hb_InetCount() returns number
of bytes received or sent in given socket in recently executed socket
read/write hb_inet*() function so seems to be alternate form of extracting
information which is returned or passed to parameter by reference by these
functions.
Thanks. I can look to code and find it myself, but the function name
does not say the meaning of it. That's, what I mean.
hb_InetRecvEndBlock() read from socket data until it receives one or
more given terminators. Probably the name is confusing - I also have to
refresh my mind checking the source code.
In general such functions are very usefull, f.e. this code in uhttpd2.prg
Nothing against additional functions with proper names. I just want to
have the basic function with the same names and same (as much as
possible) functionality!
cRequest := ""
nLen := 1
DO WHILE AT(CR_LF + CR_LF, cRequest) == 0 .AND. nLen > 0
nLen := socket_recv(hSocket, @cBuf)
cRequest += cBuf
ENDDO
Can be replaced by:
cRequest := hb_inetRecvEndBlock( hSocket, CR_LF + CR_LF )
Please also note that the original version cannot be used for protocols
which may pass additional data after double CR_LF because it's possible
that it will be read as part of cRequest and lost.
Actually, the content of cRequest is not lost. In ParseRequest() I have
to analyse http header (Content-Length, etc.) and continue receiving
request of POST method, but I have not implemented this yet.
I also think that it's not bad to implement some functions
like hb_inetRecvEndBlock() (though probably using different names ;-)) to
move some operations which may be very expensive in .prg level to .c code
so I'm not against them.
I hope that the new implementation will be much easier to understand.
Separating Harbour C API from .prg functions, cleaner definition for
base socket structure and code more closer to original BSD socket
interface should help.
I do not contradict you at all. Additional C layer is OK, additional
functions OK, but I want to have bind(), listen(), accept(), connect(),
recv(), send() (possibly with some prefixes). Nothing against
send_all(), recv_until(), etc....
Best regards,
Mindaugas
_______________________________________________
Harbour mailing list
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour