how to know how many bytes can read from a descriptor? (C/C++)
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
how to know how many bytes can read from a descriptor? (C/C++)
hiho@ll
from java doc:
Code:
class java.io.InputStream:
int available()
Returns the number of bytes that can be read (or skipped over) from this input stream without blocking by the next caller of a method for this input stream.
is it possible to do the same stuff in C/C++
using select(); i only know if i can read something, but how do i know how much i can read?
The closest I know is basic_streambuf<...>:: in_avail . It is used to see how many characters are available in the buffer. Stroustrup cautions that on some systems, it can be hard to determine if input is available.
You may also look at basic_istream<...>:: readsome. It's not exactly the same as Java's available, because it does read. But it may let you achieve what you want. Bjarne Stroustrup writes (p 644 in The C++ Programming Language, Third Edition):
Quote:
The readsome() function is a low-level operation that allows a user to peek at a stream to see if there are any characters available to read. This can be most useful when it is undesirable to wait for input, say, from a keyboard.
seems good
not 100% what i need/want but i think it's an option
thx
@jim mcnamara
i'm not sure, but your versions only work with a file
both fstat and ftell want a file not a socket
so it doesn't work with every descriptor
just with files, not?
isn't there some low level function to ask the kernel:
"how much bytes did you buffer for the descriptor 10?"
Are you sure you need to? What's wrong with trying to read() however many bytes from the descriptor and if read() returns less than that number then read() again until you get the expected number of bytes?
If you are wanting to read from a socket, you can get the number of bytes available by passing FIONREAD to ioctlsocket in Windows. In Linux, it looks like you can do a similar thing with ioctl and/or tty_ioctl, though I've never tried that before myself.
But, as itsme86 said, usually you don't really need to know how many bytes are available right now. Just read what you can and piece it together as you get it.
Originally posted by Thinking
isn't there some low level function to ask the kernel:
"how much bytes did you buffer for the descriptor 10?" [/B]
There is the select C function. But at this point, you are getting very low-level and I suspect
you will continue doing I/O with read/write (not fread, fwrite). The usage is:
Code:
int select( int ndfs, fd_set *read_fds, fd_set *write_fds, fds_set *execpt_fds, struct timeval *timeout );
For example (this may need fixing up of course):
Code:
#inlcude <sys/types.h>
#include <stdio.h>
int main( int argc, char **argv )
{
fd_set thefdset;
int maxfd;
int sockfd = 10;
struct sockaddr_in servaddr;
/* Prepare the address. */
memset( &servaddr, 0, sizeof( servaddr ) );
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons( 13 ); /* What is your target? Echo server? */
inet_pton( AF_INET, ( argc > 1 ) ? argv[1] : "127.0.0.1", &servaddr.sin_addr );
/* Setup your socket however you like. */
if( ( sockfd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ) ) < 0 )
{
fprintf( stderr, "Error doing a socket.\n" );
}
else if( ( connect( sockfd, (SA *)&servaddr, sizeof( servaddr ) ) < 0 )
{
fprintf( stderr, "Error doing a connect.\n" );
}
else
{
FD_ZERO( &thefdset );
maxfd = sockfd + 1; /* <-- If descriptor 10 is the last descriptor you want to check. */
for ( ; ; )
{
FD_SET( sockfd, &thefdset );
/* Determine which file descriptors in the file descriptor set is available for reading. */
if( select( maxfd, &thefdset, NULL, NULL, NULL ) < 0 )
{
fprintf( stderr, "Error doing a select!\n" );
break;
}
/* Check to see if the socket file descriptor was on the set of available reads. */
if( FD_ISSET( sockfd, &thefdset ) )
{
char buf[1024];
/* Flags = MSG_PEEK allows for the content to be examined without considered 'read' from the file.
* Moreover, using MSG_PEEK returns the available length that can be read using a single call to recv;
* the buffer can be much larger.
* Flags = 0 is actually read and the return value is the number of bytes actually read.
* Negative return values indicate errors.
*/
while( ( nread = recv( sockfd, buf, 1024, 0 /* Flags */ ) ) > 0 )
; /* Do something. */
if( nread < 0 ) /* 0 is done reading. */
{
fprintf( stderr, "Error doing a recv.\n" );
break;
}
}
}
/* Cleanup. */
close( sockfd );
}
return 0;
}
The late Richard Stevens has a good book on Network Programming that goes into the details of lower-level socket programming.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.