LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-28-2005, 06:52 AM   #1
Thinking
Member
 
Registered: Oct 2003
Posts: 249

Rep: Reputation: 30
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?

thx@ll
 
Old 10-28-2005, 09:44 AM   #2
Quigi
Member
 
Registered: Mar 2003
Location: Cambridge, MA, USA
Distribution: Ubuntu (Dapper and Heron)
Posts: 377

Rep: Reputation: 31
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.
 
Old 10-28-2005, 10:40 AM   #3
jim mcnamara
Member
 
Registered: May 2002
Posts: 964

Rep: Reputation: 36
one way:
Code:
struct stat st;
fstat(fileno(fp),&st); 
bytes_left= st.st_size - ftell(fp);
another way:
Code:
off_t current=ftell(fp);
fseek(fp,0,SEEK_SET);
bytes_left=ftell(fp) - current;
fseek(fp,current,SEEK_SET);  /* back to where we started */
 
Old 10-28-2005, 11:23 AM   #4
Thinking
Member
 
Registered: Oct 2003
Posts: 249

Original Poster
Rep: Reputation: 30
@Quigi

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?"
 
Old 10-28-2005, 11:46 AM   #5
itsme86
Senior Member
 
Registered: Jan 2004
Location: Oregon, USA
Distribution: Slackware
Posts: 1,246

Rep: Reputation: 59
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?
 
Old 10-28-2005, 12:01 PM   #6
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 32
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.

Last edited by deiussum; 10-28-2005 at 12:05 PM.
 
Old 10-28-2005, 12:46 PM   #7
naf
Member
 
Registered: Oct 2005
Location: Chicago, USA
Distribution: Slackware & Fedora
Posts: 66

Rep: Reputation: 15
Quote:
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.

Last edited by naf; 10-28-2005 at 12:48 PM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Custom DSDT found, read 0 bytes! So what did I miss? Simon Bridge Ubuntu 0 11-29-2005 06:41 PM
TX bytes vs. httpd bytes ovrload Linux - Networking 3 10-12-2005 04:19 PM
calling sys_read inside sys_write returns number of bytes read as zero appas Linux - Software 0 08-28-2004 07:21 AM
usb descriptor jonfa Linux - General 3 02-10-2004 06:32 PM
File descriptor lido Linux - Newbie 5 07-17-2003 11:58 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 03:26 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration