TransWikia.com

popen() vs netcat

Raspberry Pi Asked by weirdgyn on October 5, 2021

I’m writing a RPi based surveillance solution that, among other things, starts video feeds on demand.
In my very first attempt I wrote a pretty simple TCP server that listen for a connection collect the command from the client then if the command require a video feeds it forks the process and spawn a video streaming using this command line:

raspivid -n -ih -t 0 -rot 90 -w 640 -h 480 -fps 25 -b 2000000 -l -o - | nc -l -p 5000

Such command is spawned trough the following function:

void spawn_child(const char* script)
{
  child = true;
  setpgid(0, 0);
  openlog (process_name, LOG_PID | LOG_ODELAY, LOG_LOCAL0);
  syslog(LOG_INFO, "spawned: %s", script);        
  system(script);
  exit_cond = TERMINATE; 
}

where script parameter is set as the command line above…

Now I would like to have a little more control over the script running for this reason I tought to use popen() instead netcat.

This’s the new spawn_child function:

void spawn_child(const char* script)
{
  child = true;
  setpgid(0, 0);
  openlog (process_name, LOG_PID | LOG_ODELAY, LOG_LOCAL0);
  syslog(LOG_INFO, "spawned : %s", script);     
  
  syslog(LOG_INFO,"CREATING SOCKET");
  accept_socket = create_socket(video_port);
  
  video_socket = accept(accept_socket, 0, 0);
  
  syslog(LOG_INFO,"CLIENT CONNECTED");
  
  streamVideo = popen(script,"r");
      
  while(!feof(streamVideo) && !terminate)
  {
    int bytes;

    bytes = fread(video_buff, BUF_SIZE, 1, streamVideo);
        
    if(bytes > 0)
      write(video_socket,video_buff,bytes);
  }

  close(video_socket);
  pclose(streamVideo);
  
  exit_cond = TERMINATE; 
}

Of course in this case the script parameter become:

raspivid -n -ih -t 0 -rot 90 -w 640 -h 480 -fps 25 -b 2000000 -l -o -

I don’t think is the correct solution since both reading and writing calls should be managed with a different approach (threading?) but what I observe right now is a much slower output rate (of the streaming) compared with the netcat solution. Is this performance degradation due to my code structure, delays between read() and write() calls, or there’s something more I forgot?

What’s a better approach to fix this? Threading? read() and write() non blocking?

One Answer

I bet it has to do with buffering you're doing on streams. man popen has this line

Note that output popen() streams are block buffered by default.

You'll have to increase the buffer size to something more respectable than the default block size (which can be as small as 256 bytes) using setvbuf. AFAIK nc increases the buffer size to 8K.

Correct answer by Dmitry Grigoryev on October 5, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP