Hi everyone,
New user on this forum but also new to C and C++.
I was hoping someone could enlight a really beginner on something I've been struggling with in the last days.
Here is my task for an R&D Project. I've build a client app and a server app using sockets with Adobe AIR. Works well so far.
The server app is including a C compiled executable to act as a wrapper for another C library.
I've made the front (server app) talking with the C process that I launch from it. The app is basically able to send and receive data with the C process (just string for now). Pretty much like you would do from with command line.
I had 2 approaches to exchange data (just string for now):
- std::cin and std::cout
- read and write
They both work well.
The problem:
The C library I've included is using a thread to get information from a server, I made it working with some examples I had, but the example is using a usleep and it makes the while loop stopping which is a problem with the I/O I need (if I got the code right). Also the std::cin and read method stops the while loop which is a problem as I need to loop for the thread to process the events I receive from the server.
With a bit of search, I found out that what I probably need is called "non-blocking IO".
Great, but my knowledge of C is so light that I haven't been able to make any non-blocking IO examples working (I have like 6 google pages of visited links I tried to find a solution I would be able to able to understand/implement at my level)...
The closest I got is the following code (also attached as a file), which stops looping as soon as I receive an input (basically not working).
I was hoping someone could explain me a bit how I can do that (simply if possible, as I'm really a beginner), the best would be a simple command line program that shows the loop and IO working? Or tell me what is wrong in that code, in which I understand only half of it, as I tried bits and pieces from everywhere.
I understand I need to put my nose in some C, C++ book, which I will do, but right now, having this non-blocking IO working would make me able to continue.
Thanks in advance for any help.
Romuald
Code:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <signal.h>
#include <pthread.h>
#include <string>
#include <sstream>
#include <iostream>
#include "appkey.h"
#include "libspotify/api.h"
#include "spotify.h"
#include <sys/socket.h>
#include <termios.h>
#define STDIN 0 // file descriptor for standard input
#define BUFFER_SIZE 8192
#define NB_ENABLE 0
#define NB_DISABLE 1
bool exitloop = false;
pthread_t mainthread = 0;
char buf[BUFFER_SIZE];
static void sigIgn(int signo) { }
int kbhit() {
struct timeval tv;
fd_set fds;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0
select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
return FD_ISSET(STDIN_FILENO, &fds);
}
void nonblock(int state) {
struct termios ttystate;
//get the terminal state
tcgetattr(STDIN_FILENO, &ttystate);
if (state==NB_ENABLE) {
//turn off canonical mode
ttystate.c_lflag &= ~ICANON;
//minimum of number input read.
ttystate.c_cc[VMIN] = 1;
}
else if (state==NB_DISABLE) {
//turn on canonical mode
ttystate.c_lflag |= ICANON;
}
//set the terminal attributes.
tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
}
int main(int argc, char* argv[]) {
int i = 0;
int cnt;
mainthread = pthread_self();
signal(SIGIO, &sigIgn);
if(spotify->InitSession())
printf("valid session.\n");
else
printf("invalid session.\n");
spotify->SetCredentials("*************", "**************");
spotify->Login();
sigset_t sigset;
sigemptyset(&sigset);
sigaddset(&sigset, SIGIO);
nonblock(NB_ENABLE);
while(!i) {
i=kbhit();
if (i!=0) {
while (!feof(stdin)) {
cnt = read(STDIN_FILENO, buf, sizeof buf);
write(STDOUT_FILENO, buf, cnt );
}
}
int timeout = -1;
pthread_sigmask(SIG_BLOCK, &sigset, NULL);
spotify->ProcessEvents(&timeout);
pthread_sigmask(SIG_UNBLOCK, &sigset, NULL);
}
nonblock(NB_DISABLE);
return 0;
}