WSAStartup( wVersionRequested, &wsaData );
SOCKET sock;
sock = socket(AF_INET, SOCK_STREAM, NULL);
SOCKADDR_IN sin;
u_short alport = 80;
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = 0;
sin.sin_port = htons(alport);
int nBind = bind(sock, (LPSOCKADDR)&sin, sizeof (sin));
SOCKET sockAccept;
sockaddr incoming;
int incoming_size = sizeof(sockaddr);
while (true)
{
listen(sock, SOMAXCONN);
sockAccept = accept(sock, &incoming, &incoming_size);
char buf[1024];
int nBytesReceived = 0;
problem here ....................................................
nBytesReceived = recv(sockAccept, buf, 1024, 0);
InterpretHTTP(buf, sockAccept);
}
WSACleanup();
This seems to be working just fine as long as the recv buffer is large
enough to handle the incoming request. If it's not, though (if I set
the buffer size to 10, just to test my code), recv returns 10 rather
than SOCKET_ERROR followed by WSAEMSGSIZE (as the documentation
suggests it should).
Am I skipping a step somewhere?
Thanks!
Public Function IsDataAvailable() As Boolean
Dim readfds As fd_set, writefds As fd_set, exceptfds As fd_set
Dim timeout As TIME_VAL
Dim lngResult As Long, nfds As Long
nfds = 0
timeout.tv_sec = 25
timeout.tv_usec = 0
readfds.fd_count = 1
readfds.fd_array(0) = Sock
writefds.fd_count = 0
exceptfds.fd_count = 0
lngResult = ws_select(nfds, readfds, writefds, exceptfds, timeout)
If lngResult = SOCKET_ERROR Then
SetLastErrorCode = "Error in IsDataAvailable::select"
IsDataAvailable = False
Else
If lngResult > 0 Then IsDataAvailable = True Else IsDataAvailable =
False
End If
End Function
I just use a loop checking to see if this function returns true, and if it
does perform another recv.
If this is a slow way of doing it or I just talking utter crap then any
better ways would be helpful
Cheers,
Dean
Reader <nob...@nowhere.net> wrote in message
news:38a92ec9...@news3.newscene.com...
Probably. :) (Hint: check out 'ioctlsocket')
Winsock will return to you as much data as is available up to the amount
you ask for.
That is, if there is *more* than X bytes, it will only give you X bytes
because that's all you asked for. (i.e. it's *not* considered an error to
ask for *less* than how much there actually is).
(Besides, it can't very well give you *more* than you asked for! If it did,
it would overflow your buffer! Thus it will only give you as much as it has
up to however much you ask for.)
On the flip side, if there is *less* than X bytes available, it can only
give you however much it has and no more. (Duh!)
Thus the reasoning for passing back how much it actually gave you via the
return code (which can be different from however much you asked for).
If you ask for X bytes and the return code from 'recv' is *less* than X
bytes, you're done; that's all there is.
(Note: of course you'll have to check for both cases of SOCKET_ERROR and
the case where 'recv' returns 0 bytes, indicating the connection has been
gracefully closed by the other end).
If you ask for X bytes and 'recv' returns you X bytes, you got all you
asked for, BUT... there *could* (as in *maybe* but not necessarily) be
still more waiting to be read.
What you should probably be doing is using 'ioctlsocket' with the FIONREAD
option to find out how much there actually *is* so you can read it *all*:
// Block until there's some data to be read...
char peek;
int nRetCode;
if ((nRetCode = recv(sock,&peek,1,MSG_PEEK)) != 1)
{
if (nRetCode == 0)
{
// Connection has been closed...
}
// else SOCKET_ERROR; handle appropriately...
}
If the above 'recv' returns '1', it worked; there's data on the socket
waiting to be read. Now what you need to do is find out *how much* data
there is. Use 'ioctlsocket' for that:
unsigned long nBytesAvail;
if (ioctlsocket(sock,FIONREAD,&nBytesAvail) == SOCKET_ERROR)
{
// Error; handle appropriately...
}
Now you know how much there actually is. To read it all in at once, simply
create a buffer large enough and read it in!
char* pBuffer = new char[nBytesAvail];
int nBytesRead = recv(sock,pBuffer,nBytesAvail,0);
if (nBytesRead == SOCKET_ERROR)
{
delete [] pBuffer;
// handle error appropriately...
}
// Process data in pBuffer....
> Thanks!
You're welcome. :)
--
"Fish" (David B. Trout)
(spamblocks in place; actual
e-mail address follows below)
Fish posted the following to alt.winsock.programming:
<snip my original reply>
I'm also hoping that we're not seeing all of your code here. I'm hoping
that you simply snipped out the portion of your code that closes the socket
when it's done with it (before 'accept'ing the next connection request).
Your loop, as you present it above, will eventually run out of sockets.
Each 'accept' creates a brand new socket and I don't see where you're
closing the "sockAccept" socket before reusing it in the next 'accept'.
(For that matter, I don't see where you're ever closing your listening
socket -- 'sock' -- either.)
As I said, I'm assuming you just trimmed that logic out before making your
post. :)
(I just thought I'd mention that in case anyone else out there trying to
learn sockets programming makes the mistake of copying your "technique.")
<pruned>
> problem here ....................................................
> nBytesReceived = recv(sockAccept, buf, 1024, 0);
> InterpretHTTP(buf, sockAccept);
> }
>
> WSACleanup();
>
> This seems to be working just fine as long as the recv buffer is large
> enough to handle the incoming request. If it's not, though (if I set
> the buffer size to 10, just to test my code), recv returns 10 rather
> than SOCKET_ERROR followed by WSAEMSGSIZE (as the documentation
> suggests it should).
When using TCP, you cannot rely on the recv() call to return
messages. You read a number of bytes, and look for the record
terminator sequence (CR LF). Typically, you use a loop to
read bytes from the socket, and you stop when you see the
terminating sequence. Feel free to be more efficient by buffering
the stream in your program, although with HTTP it doesn't really
make a difference (but with today's really long URLs it might :-).
I'd suggest you buy a good book (the late W Richard Stevens' books
are classics) to learn about socket programming fundamentals.
Take care,
--
Stefaan
--
--PGP key available from PGP key servers (http://www.pgp.net/pgpnet/)--
Ninety-Ninety Rule of Project Schedules:
The first ninety percent of the task takes ninety percent of
the time, and the last ten percent takes the other ninety percent.