How to read incoming packets of chars 
Author Message
 How to read incoming packets of chars

/ I have a very simple question: I need to wait for a incoming packet of
/ char that does not end with a cr.
/ I need a function that returns a char if present in the input buffer and
/ returns something else if there are no chars waiting. I am using a ANSI
/ C compiler with a 6811.

You might try turning off bufferring, something like
setvbuf(file,0,_IONBF_,0). With fgetc this should go to the operating
system for each character. This will hang until the next character comes
into existence, or end of file or error is reported.

Your system might also provide something like read() which might give you
more control over delays.

--
CACS: Collective Against Consensual Sanity       v0.123
Now a text site map! http://www.*-*-*.com/
pretty?     http://www.*-*-*.com/
Please   do  not   feed   or   annoy  the  kibologists.



Sun, 16 Jun 2002 03:00:00 GMT  
 How to read incoming packets of chars
Hello to all,
I have a very simple question: I need to wait for a incoming packet of
char that does not end with a cr.
I need a function that returns a char if present in the input buffer and
returns something else if there are no chars waiting. I am using a ANSI
C compiler with a 6811.
If I use getchar it waits for a cr and this is not good, since the
packet could be altered during transmission I can't rely on a specific
char as end of packet indication.
I would also to know if it is normal since I would aspect that function
would not wait if no char is present.
Thanks,


P.S. remove nospam to reply



Mon, 17 Jun 2002 03:00:00 GMT  
 How to read incoming packets of chars


Quote:
>/ I have a very simple question: I need to wait for a incoming packet of
>/ char that does not end with a cr.
>/ I need a function that returns a char if present in the input buffer and
>/ returns something else if there are no chars waiting. I am using a ANSI
>/ C compiler with a 6811.

>You might try turning off bufferring, something like
>setvbuf(file,0,_IONBF_,0). With fgetc this should go to the operating
>system for each character. This will hang until the next character comes
>into existence, or end of file or error is reported.

The standard I/O library does not delay the delivery of characters to the
application. As soon as input is available from the environment, it is
available to the application. The getc function does not wait until a full line
of input is accumulated.  The line buffering is caused by something else; the
input device itself or the underlying operating system.  Changing the buffering
strategy won't affect that.

The answer lies in some platform specific functions for making the input behave
in the desired way. Drawing on a POSIX example: in a POSIX system, you could
use the tcsetattr() function to put the terminal device into character at a
time mode. Then getchar() will happily return for each character received.



Mon, 17 Jun 2002 03:00:00 GMT  
 How to read incoming packets of chars
Thanks for the answer(answers?),
but the problem should not be the OS, I don't have it!
There is no buffering device, maybe the runtime environment but I found that every
input char function in the end references fgetc.
I have found the source inside the development tool it seems that the "problem"
lies in the function itself.
Maybe I am too lazy to ask someone to tell me if and how I could modify/clone this
function to achieve a immediate return upon invocation without waiting for a NL/CR?

Thanks in advance,


P.S. I will try anyway but I would have other opinions, I think that me and C will
never be good friends...

Here is the source:
//////////////////////////////////////////////////////////////////////
/*-
 * Copyright (c) 1996 Introl Corporation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 * This product includes software developed by Introl Corporation.
 * 4. The name of Introl Corporation shall not be used to endorse or
 *    promote products derived from this software without specific
 *    prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY INTROL CORPORATION ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL INTROL CORPORATION BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */
/*
 * fgetc - read a character using
 */

#include <stdio.h>

int __Pascal
fgetc(FILE *stream)
 {
 unsigned char flags = stream->f_io_params.io_flags;
 int c;

 /* In line buffered mode, characters are returned from the buffer
  * if it is not empty, otherwise the buffer is refilled by gathering
  * input until a newline is read.
  */
 if (stream->f_io_params.io_flags & _IO_BUFF)
  {
  /* If the pointer is valid the buffer contains something, we return
   * the next character within the buffer.
   */
  if (stream->f_buffptr && stream->f_cnt)
   {
  hasbuf:
   --stream->f_cnt;
   return *stream->f_buffptr++;
   }

  /* Otherwise read until a newline is input.
   */
  else
   {
   char *s = stream->f_buffer;

   do
    {
    c = (stream->f_read)();

    /* Perform any necessary input translations.
     * Carriage returns can be translated into
     * a newline.  Line kill characters can be
     * eliminated.  They cause the buffer to by
     * emptied.
     */
    if ((flags & _IO_ICRNL) && c == '\r')
     c = '\n';
    else if (c == stream->f_io_params.io_kill)
     {
     fputc('\n', stream);
     s = stream->f_buffer;
     continue;
     }

    /* Put the character in the buffer (unless
     * it's the backspace character in which case we
     * remove the last character from the buffer).
     */
    if (c == stream->f_io_params.io_erase)
     {
     if (s != stream->f_buffer)
      {
      if (flags & _IO_ECHO)
       fputc(c, stream);
      --s;
      }
     }
    else
     {
     /* Echo the character if necessary.
      */
     if (flags & _IO_ECHO)
      fputc(c, stream);
     *s++ = c;
     }
    }
   while (c != '\n');
   stream->f_buffptr = stream->f_buffer;
   stream->f_cnt = s - stream->f_buffer;
   goto hasbuf;
   }
  }

 /* Unbuffered input uses the device's low-level input function
  * (with possible echo).
  */
 else
  {
  c = (stream->f_read)();
  if (flags & _IO_ECHO)
   fputc(c, stream);
  }
 return c;
 }

//////////////////////////////////////////////////////////////////////

Quote:



> >/ I have a very simple question: I need to wait for a incoming packet of
> >/ char that does not end with a cr.
> >/ I need a function that returns a char if present in the input buffer and
> >/ returns something else if there are no chars waiting. I am using a ANSI
> >/ C compiler with a 6811.

> >You might try turning off bufferring, something like
> >setvbuf(file,0,_IONBF_,0). With fgetc this should go to the operating
> >system for each character. This will hang until the next character comes
> >into existence, or end of file or error is reported.

> The standard I/O library does not delay the delivery of characters to the
> application. As soon as input is available from the environment, it is
> available to the application. The getc function does not wait until a full line
> of input is accumulated.  The line buffering is caused by something else; the
> input device itself or the underlying operating system.  Changing the buffering
> strategy won't affect that.

> The answer lies in some platform specific functions for making the input behave
> in the desired way. Drawing on a POSIX example: in a POSIX system, you could
> use the tcsetattr() function to put the terminal device into character at a
> time mode. Then getchar() will happily return for each character received.



Mon, 17 Jun 2002 03:00:00 GMT  
 How to read incoming packets of chars


Quote:
>/ I have a very simple question: I need to wait for a incoming packet of
>/ char that does not end with a cr.
>/ I need a function that returns a char if present in the input buffer and
>/ returns something else if there are no chars waiting. I am using a ANSI
>/ C compiler with a 6811.

>You might try turning off bufferring, something like
>setvbuf(file,0,_IONBF_,0).

_IONBF has no training _.

This will make no difference. The standard library input buffering
will always make a character available immediately if it has one buffered
or wait if it doesn't and one is unavailable from the input source. It
isn't the C library bufferling that waits for a cr (because it can't), it
is whatever low level driver (such as a keyboard driver) that is sourcing
the data.

Quote:
>With fgetc this should go to the operating
>system for each character. This will hang until the next character comes
>into existence, or end of file or error is reported.

And the operating system will still not release the data until a cr
as been entered.

Quote:
>Your system might also provide something like read() which might give you
>more control over delays.

A POSIX-style read() function will suffer the same problem. To solve
this problem you need to configure the OS not to wait for cr (e.g.
using termios/tcsetattr in a POSIX environment) or use an alternative
system call that bypasses this mechanism (e.g. getch() or getche() on
some DOS compilers). There is no standard solution to this.

Section 19.1 of the FAQ addresses this very issue in some detail.

--
-----------------------------------------


-----------------------------------------



Mon, 17 Jun 2002 03:00:00 GMT  
 How to read incoming packets of chars


Quote:
>Thanks for the answer(answers?),
>but the problem should not be the OS, I don't have it!

OK, whoever implemented this is trying to place some of "OS" facilities
in the code of the standard library itself. That's OK as long as
it does the right thing. Unfortunately in this case it doesn't.

Quote:
>There is no buffering device, maybe the runtime environment but I found that
> every
>input char function in the end references fgetc.
>I have found the source inside the development tool it seems that the "problem"
>lies in the function itself.
>Maybe I am too lazy to ask someone to tell me if and how I could modify/clone
> this
>function to achieve a immediate return upon invocation without waiting for a
> NL/CR?

It depends on how the implementation sets the flags this code tests for
e.g. under what precise conditions

  if (stream->f_io_params.io_flags & _IO_BUFF)

tests true. By the look of it this is propbably related to the buffering
mode set by setbuf() or setvbuf() so a setbuf(fp, NULL) or
setvbuf(fp, NULL, _IONBF, 0), as another poster indicated, might do what
you need. Looking at the code

...

Quote:
>#include <stdio.h>

>int __PASCAL
>fgetc(FILE *stream)
> {
> unsigned char flags = stream->f_io_params.io_flags;
> int c;

> /* In line buffered mode, characters are returned from the buffer
>  * if it is not empty, otherwise the buffer is refilled by gathering
>  * input until a newline is read.
>  */
> if (stream->f_io_params.io_flags & _IO_BUFF)

This appear to test whether buffering is enabled for the stream (although
after setting up the flags variable above I don't know why it doesn't use it).
There doesn't seem to be any distinction made between line buffering
and full buffering.

Quote:
>  {
>  /* If the pointer is valid the buffer contains something, we return
>   * the next character within the buffer.
>   */
>  if (stream->f_buffptr && stream->f_cnt)
>   {
>  hasbuf:
>   --stream->f_cnt;
>   return *stream->f_buffptr++;
>   }

So if there is something in the buffer the function will always
return immediately. The problem is with the following code which
fills the buffer. It implements rudimetary line editing and reads
characters until it encounters a cr (which may be converted to a
new-line).

Quote:
>  /* Otherwise read until a newline is input.
>   */
>  else
>   {
>   char *s = stream->f_buffer;

>   do
>    {
>    c = (stream->f_read)();

This is the call to the lower level code that reads a character. It is
performed through a function pointer stored in the FILE datastructure.

Quote:
>    /* Perform any necessary input translations.
>     * Carriage returns can be translated into
>     * a newline.  Line kill characters can be
>     * eliminated.  They cause the buffer to by
>     * emptied.
>     */
>    if ((flags & _IO_ICRNL) && c == '\r')
>     c = '\n';
>    else if (c == stream->f_io_params.io_kill)
>     {
>     fputc('\n', stream);
>     s = stream->f_buffer;
>     continue;
>     }

>    /* Put the character in the buffer (unless
>     * it's the backspace character in which case we
>     * remove the last character from the buffer).
>     */
>    if (c == stream->f_io_params.io_erase)
>     {
>     if (s != stream->f_buffer)
>      {
>      if (flags & _IO_ECHO)
>       fputc(c, stream);
>      --s;
>      }
>     }
>    else
>     {
>     /* Echo the character if necessary.
>      */
>     if (flags & _IO_ECHO)
>      fputc(c, stream);
>     *s++ = c;

I see there is no buffer bounds checking here. {*filter*}. You can crash
the program just by typing too much on a line.

Quote:
>     }
>    }
>   while (c != '\n');
>   stream->f_buffptr = stream->f_buffer;
>   stream->f_cnt = s - stream->f_buffer;
>   goto hasbuf;
>   }
>  }

Some gotos are justifed, gere's one that isn't. :-)

The following is the code that is executed when the stream is
unbuffered (I assume). It reads a character and passes it straight back
to the caller.

Quote:
> /* Unbuffered input uses the device's low-level input function
>  * (with possible echo).
>  */
> else
>  {
>  c = (stream->f_read)();
>  if (flags & _IO_ECHO)
>   fputc(c, stream);
>  }
> return c;
> }

--
-----------------------------------------


-----------------------------------------


Mon, 17 Jun 2002 03:00:00 GMT  
 How to read incoming packets of chars


Quote:
> In article


Quote:

> >You might try turning off bufferring, something like
> >setvbuf(file,0,_IONBF_,0).

> _IONBF has no training _.

In which case, could you suggest a suitable course which it might attend in
an attempt to rectify this omission?

:-)



Tue, 18 Jun 2002 03:00:00 GMT  
 How to read incoming packets of chars


Quote:


>> In article


>> >You might try turning off bufferring, something like
>> >setvbuf(file,0,_IONBF_,0).

>> _IONBF has no training _.

>In which case, could you suggest a suitable course which it might attend in
>an attempt to rectify this omission?

Typing for the ham-fisted.

--
-----------------------------------------


-----------------------------------------



Thu, 20 Jun 2002 03:00:00 GMT  
 
 [ 12 post ] 

 Relevant Pages 

1. char **packet problem

2. Request: HOWTO on reading network packets

3. Reading Hex from File and Putting it in a Packet

4. reading control characters from a IPv4 packet

5. mic incoming volume level - mm api′s

6. mic incoming volume level - mm api′s

7. RAS incoming connections

8. How can I catch incoming dialup logon

9. Changing Baudrate For Incoming PPP Unimodem Port

10. Setting up an incoming RAS

11. accepting incoming connections via USB PocketPC2002

12. Incoming calls

 

 
Powered by phpBB® Forum Software