PIPE - Hello World 2001

(CGI Bash; C Network Daemon; Java Applet Network Socket)


 

  • Environment:

This following are assumed throughout this guide:

  • Red Hat Linux 7.1
Download the Demo sample, extract it and test it.

 

  • Introduction:

The purpose of this sample is to demonstrate how a server process pipes standard output to the network socket.


          

 

  • Create "./netsockd.c":

#include <stdlib.h>
#include <netinet/in.h>

#include <sys/types.h>
#include <sys/socket.h>

#define SERVER_TCP_PORT   12345
//#define SERVER_IP_ADDRESS 2130706433
#define SERVER_IP_ADDRESS 0
#define BUFFER_SIZE 1024

void serve_connection
(
  int socket_value
)
{
  char charbuf[BUFFER_SIZE];
  char * charbufptr;
  int  pid;
  int  fd[2];

  for (;;)
  {
    if (pipe(fd) != 0)
    {
      perror("pipe");
      exit(EXIT_FAILURE);
    }

    pid = fork();

    if (pid == -1)
    {
      perror("pipe");
      exit(EXIT_FAILURE);
    }

/* child */
    if (pid == 0)
    {
      close(fd[1]);
      close(0);
      dup(fd[0]);

      charbufptr = &(charbuf[0]);
      memset(charbufptr, 0, BUFFER_SIZE);
      read(fd[0], charbufptr, BUFFER_SIZE);
      charbuf[strlen(charbuf)] = '\n';
      write(socket_value, charbuf, (int) strlen(charbuf));
//      fflush(socket_value);

      close(fd[0]);
      sleep(6);
    }

/* parent */
    if (pid != 0)
    {
      close(fd[0]);
      close(1);
      dup(fd[1]);
      close(fd[1]);
      if (execlp("/bin/date", "", NULL) == -1)
      {
        perror("parent");
        exit(EXIT_FAILURE);
      }
    }
  }

  return;
}

int main
(
)
{
  struct sockaddr_in server_address;
  int                server_socket;
  struct sockaddr_in client_address;
  int                client_address_size;
  int                current_socket;
  pid_t              process_id;

  bzero((char *) &(server_address), sizeof(server_address));
  server_address.sin_family      = AF_INET;
  server_address.sin_port        = htons(SERVER_TCP_PORT);
  server_address.sin_addr.s_addr = htonl(SERVER_IP_ADDRESS);

  if ((server_socket = socket(PF_INET, SOCK_STREAM, 0)) < 0)
  {
    perror("socket");
    exit(EXIT_FAILURE);
  }

  if (bind
      (
        server_socket,
        (struct sockaddr *) (&(server_address)),
        sizeof(server_address)
      ) < 0)
  {
    perror("bind");
    exit(EXIT_FAILURE);
  }

  listen(server_socket, 5);

  for (;;)
  {
    client_address_size = sizeof(client_address);
    current_socket =
      accept
      (
        server_socket,
        (struct sockaddr *) &(client_address),
        &(client_address_size)
      );

    if (current_socket < 0)
    {
      perror("accept");
      exit(EXIT_FAILURE);
    }

    if ((process_id = fork()) < 0)
    {
      perror("fork");
      exit(EXIT_FAILURE);
    }

    if (process_id > 0)
    {
      close(current_socket);
      continue;
    }

    close(server_socket);
    serve_connection(current_socket);
  }

  return EXIT_SUCCESS;
}

 

  • Create "./NetsockClient.java":

/*
// /usr/bin/appletviewer index.html
*/

import java.lang.*;
import java.applet.*;
import java.awt.*;
import java.net.*;
import java.io.*;
import java.util.*;

public class NetsockClient extends java.applet.Applet
{
  public java.awt.GridBagLayout gridBagLayout;
  public java.awt.TextArea      textArea;
  public java.net.Socket        socket;

  public NetsockClient
  (
  )
  {
    this.gridBagLayout = new java.awt.GridBagLayout();
    this.textArea      = new java.awt.TextArea();

    return;
  }

  public void init
  (
  )
  {
    super.init();

    if (this.connect() != true)
    {
      java.lang.System.exit(0);
    }

    this.setLayout(this.gridBagLayout);

    this.addComponent(this.textArea, 1, 1, 1, 1,
                      0, 0, java.awt.GridBagConstraints.NONE);

    return;
  }

  public synchronized void start
  (
  )
  {
    java.io.DataInputStream  dataInputStream;
    Reporter                 reporter;

    try
    {
      dataInputStream =
        new java.io.DataInputStream
        (
          this.socket.getInputStream()
        );

      reporter = new Reporter(dataInputStream, this.textArea);
      reporter.start();
    }
    catch
    (
      java.lang.Exception exceptionValue
    )
    {
      java.lang.System.err.println(exceptionValue.getMessage());

      java.lang.System.exit(0);
    }

    return;
  }

  public void addComponent
  (
    java.awt.Component c,
    int                row,
    int                column,
    int                width,
    int                height,
    int                weightxValue,  // can grow wider
    int                weightyValue,  // can grow taller
    int                fillValue
  )
  {
    java.awt.GridBagConstraints gbConstraints =
      new java.awt.GridBagConstraints();

    gbConstraints.gridx = column;
    gbConstraints.gridy = row;

    gbConstraints.gridwidth  = width;
    gbConstraints.gridheight = height;

    gbConstraints.weightx = weightxValue;
    gbConstraints.weighty = weightyValue;

    gbConstraints.fill = fillValue;

    this.gridBagLayout.setConstraints(c, gbConstraints);
    this.add(c);

    return;
  }

  public boolean connect
  (
  )
  {
    boolean          flag;
    java.lang.String domainName;

    domainName = new java.lang.String("localhost.localdomain");

    flag = true;

    try
    {
      this.socket = new java.net.Socket(domainName, 12345);
    }
    catch
    (
      java.lang.Exception exceptionValue
    )
    {
      flag = false;
    }

    return flag;
  }
}

class Reporter extends java.lang.Thread
{
  java.io.DataInputStream dataInputStream;
  java.awt.TextArea       textArea;

  public Reporter
  (
    java.io.DataInputStream dataInputStreamValue,
    java.awt.TextArea       textAreaValue
  )
  {
    super();

    this.dataInputStream = dataInputStreamValue;
    this.textArea        = textAreaValue;

    return;
  }

  public synchronized void run
  (
  )
  {
    char             character;
    java.lang.String string;

    for (;;)
    {
      try
      {
        character = (char) this.dataInputStream.read();
        if (character == '\0')
        {
          this.textArea.setText("");
        }

        this.textArea.setText
        (
          this.textArea.getText() +
          character
        );

//        this.sleep(0);
      }
      catch
      (
        java.lang.Exception exceptionValue
      )
      {
        break;
      }
    }

    return;
  }
}

 

  • Create "./netsock.bash":

#!/bin/bash
CLASSNAME="NetsockClient.class";
/bin/echo "Content-Type: text/html";
/bin/echo "";
/bin/echo "<applet code=\"${CLASSNAME}\" height=\"400\" width=\"600\"></applet>";

 

  • Test Demo:

# Place all the sources in /var/www/cgi-bin (Apache's default CGI-BIN directory)
/bin/cp netsockd.c NetsockClient.java netsock.bash /var/www/cgi-bin

# Restart the Apache server
/sbin/service httpd restart

# Rebuild and restart
/bin/rm *.class;/usr/bin/javac *.java
/usr/bin/killall netsockd;/bin/ps -auwx | /bin/grep netsock
/bin/netstat -atnpl | /bin/grep "12345"
/bin/rm ./netsockd;/usr/bin/make netsockd;./netsockd &

# To access the C socket daemon with the Java Applet socket, e.g.
http://localhost.localdomain/cgi-bin/netsock.bash

 

  • Troubleshooting:

- If the NetsockClient applet does not inittialise properly,
make sure that the fully qualified domain name in NetsockClient.java
is resolvable. e.g. "localhost.localdomain" This domain name refers
to the host that this applet file will be stored and called by other
applet client, e.g. web browser, applet viewer.


 

Primac Systems Limited

Copyright 2001

 

Hosted by www.Geocities.ws

1