Working on an assignment for class and have been battling ncurses for a while now (it's new to me). Creating a program that is able to communicate with another instance of the same program across a network. Part of the program is to interactively get characters from keyboard and send them to the receiving side. (We have been advised to do this with single thread approach and using getch in ncurses, with nonblocking input from getch).
The issue I'm running into is that my getch
is having behavior I cannot figure out. In different variations, it would either display every other character I type, and it won't display the most recently typed character until another character is typed after it. I've used nodelay()
to get the live input, but .
Here is the setup for my ncurses display. (Note: I used noecho()
as later I don't want to display every char that is enter).
/* initialize ncurses */
setlocale(LC_ALL,"");
initscr();
cbreak();
noecho();
nodelay(stdscr, TRUE);
nonl();
intrflush(stdscr, FALSE);
keypad(stdscr, TRUE);
clear();
Here is the code I wrote that works with getch
and sending/receiving the data over the socket.
while(1) {
rfdset = master;
if (select(maxfd + 1, &rfdset, NULL, NULL, NULL) < 0) {
perror("select");
exit(EXIT_FAILURE);
}
ch = getch();
if (ch != ERR) {
printw("%c",ch);
write(direct, &ch, 1); // direction to send data
}
for(i = 0; i <= maxfd; i++) {
if (FD_ISSET(i, &rfdset)) {
bzero(msgbuf, MSGSIZE);
idx = read(i, msgbuf, MSGSIZE);
if (i != STDIN)
printw("%s",msgbuf); // display received msg
}
}
}
When I run this and type data on any end of the application, I get results as follows:
Computer 1 keyboard input: testing123
Computer 1 screen display: tsig2
Computer 2 message recv'd: tsig2
Because of this, I feel certain that getch
is causing most of my issues, and I must be missing or doing something incorrectly in my implementation. Any advice is appreciated.
Edit 1:
I managed to resolve the every other character issue by removing the for loop and just checking the sockets directly for input. I am baffled why this fixed it. Now my only remaining issue is why is a character not displayed until a character is entered after it. Here is my revised code in the while loop:
while(1) {
rfdset = master;
if (select(maxfd + 1, &rfdset, NULL, NULL, NULL) < 0) {
perror("select");
exit(EXIT_FAILURE);
}
ch = getch();
if (ch != ERR) {
printw("%c",ch);
write(direct, &ch, 1);
}
/* check for incoming data from left socket */
if (!NOLEFT && FD_ISSET(lcsad, &rfdset)) {
bzero(leftmsg, MSGSIZE);
idx = read(lcsad, leftmsg, MSGSIZE);
leftmsg[idx] = 0;
printw("%s", leftmsg);
lm = 1;
}
/* check for incoming data from right socket */
if (!NORIGHT && FD_ISSET(rsd, &rfdset)) {
bzero(rghtmsg, MSGSIZE);
idx = read(rsd, rghtmsg, MSGSIZE);
rghtmsg[idx] = 0;
printw("%s", rghtmsg);
rm = 1;
}
/* check and send left message onward */
if (lm && !NORIGHT) {
write(direct, leftmsg, MSGSIZE);
}
/* check and send right message onward */
if (rm && !NOLEFT) {
write(direct, rghtmsg, MSGSIZE);
}
lm, rm = 0;
}
< >< >`
Result is the same on both machines.