A forum for questions and answers about network programming on Linux and all other Unix-like systems

You are not logged in.

#1 2002-07-26 11:23 PM

From: Colombia
Registered: 2002-06-12
Posts: 353

Re: 4.13 - How can I read only one character at a time?


This question is usually asked by people who are testing their server with telnet, and want it to process their keystrokes one character at a time. Without special direction from the server telnet will buffer each line of text that you type, so when you press a key, telnet won't send it until you press enter. The correct way to read a single character is (as you would expect):

read(s,buf,1) or recv(s,buf,1,flags)

The rest of this answer assumes that you want to force telnet to send individual characters and not do line buffering.

According to Roger Espel Llima ([email protected]), you can have your server send a sequence of control characters: 0xff 0xfb 0x01 0xff 0xfb 0x03 0xff 0xfd 0x0f3, which translates to IAC WILL ECHO IAC WILL SUPPRESS-GO-AHEAD IAC DO SUPPRESS-GO-AHEAD. For more information on what this means, check out std8, std28 and std29. Roger also gave the following tips:

This code will suppress echo, so you'll have to send the characters the user types back to the client if you want the user to see them.
Carriage returns will be followed by a null character, so you'll have to expect them.
If you get a 0xff, it will be followed by two more characters. These are telnet escapes.

Thanks to Cyrus Patel ([email protected]) for emailing me some pointers on clarifying this answer.

From: lore

Try this:

char gimme_char(int fd) {
char * buf = (char *)NULL; buf = (char *)malloc(1);
if (recv(fd, buf, 1, 0)) return ((char)*buf); }

From: GinShinzou

ok this code is very sloppy (no offense, but i see malloc and no free...)
what you didn't realize is that malloc keeps the memory assigned until the application terminates. you should allways put free() as close to the malloc call as possible.
if you use this code, you'll get a really, really big memory leak lol. especially in server applications, who tend to read massive amounts of data and stay up for days at a time!

try this:

char gimme_char(int fd) 
char buf; 
if ( recv(fd, &buf, 1, 0) ) return buf; 
else return '\0'; 

it's much easier to understand too!
this will sleep until a character is available to read. if an error occurs (like the connection terminating), it will return a null character.


Board footer

Powered by FluxBB