prefect
Home Engineering Publications
DACS: TCP/IP Server Library Code, server.c
 
  next up previous contents
Next: VHDL Code Up: MIDI Controller Previous: TCP/IP Server Library Header,   Contents

TCP/IP Server Library Code, server.c

The following code provides easy access to Berkeley sockets to set up a server in a Unix environment.
/*****************************************************************************
 * DACS : Distributed Audio Control System
 *============================================================================
 *         File: server.c
 *  Description: TCP/IP server routines
 *       Author: Stephen S. Richardson
 * Date Created: 04.23.95
 *  Environment: GNU C Compiler (GCC) v2.7.1, Linux i486 v2.0.28
 *        Build: library
 *============================================================================
 * The code, executables, documentation, firmware images, and all related
 * material of DACS are  
 * Copyright (C) 1997 Stephen S. Richardson - ALL RIGHTS RESERVED
 *****************************************************************************
 * Source code control:
 *
 * $Id: server.c,v 1.1 1997/07/25 12:15:37 prefect Exp prefect $
 *
 *****************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netdb.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include "server.h"

/*****************************************************************************
 establishes a tcp server on hostname at port

 returns a socket if it works, or

 ERROR_BADHOST if a bad host was specified
 ERROR_SOCKET if there's a socket error
 ERROR_BIND if there's a bind error
 ERROR_LISTEN if there's a listen error
 *****************************************************************************/
int tcpEstablishServer (char *hostname, int port)
{
  struct sockaddr_in saddr;
  struct hostent *hp;
  int s;
  
  memset (&saddr,0,sizeof (saddr));
  saddr.sin_family = AF_INET;
  hp = gethostbyname (hostname);
  if (hp == NULL) return (ERROR_BADHOST);
  
  bzero ((char *) &saddr.sin_addr, hp->h_length); 

  saddr.sin_port = htons (port);
  
  s = socket (AF_INET,SOCK_STREAM,0);
  if (s== -1) return (ERROR_SOCKET);

  if (bind (s, (struct sockaddr *) &saddr, sizeof (saddr)) !=0)
    return (ERROR_BIND);

  if (listen (s,1) !=0) return (ERROR_LISTEN);  /* queue 1 request only */

  return (s);
}



/*****************************************************************************
 accepts a connection from a client, returning a socket file descriptor
 needs the port socket and an ipaddx pointer passed to it (it gets filled in
 with the ip address of the host connecting to the server)

 returns socket file descriptor, or

 ERROR_ACCEPT if accept errors out more than 255 times.
 *****************************************************************************/

int tcpAcceptConn (int s, struct ipaddx *ip)
{
  struct sockaddr_in addr;
  struct hostent *b;
  int sfd, addrlen, x=0;

  addrlen = sizeof (struct sockaddr_in);

  do {
    sfd = accept (s, (struct sockaddr *) &addr,&addrlen);
    x++;
  } while ((sfd<0)&&(x<=255));
  if (x>=255) return (ERROR_ACCEPT);

  b = gethostbyaddr ((char *)&addr.sin_addr.s_addr, sizeof (addr.sin_addr.s_addr),AF_INET);

  ip->first = addr.sin_addr.s_addr & 0x000000FF;
  ip->second = (addr.sin_addr.s_addr & 0x0000FF00)>>8;
  ip->third = (addr.sin_addr.s_addr & 0x00FF0000)>>16;
  ip->fourth = (addr.sin_addr.s_addr & 0xFF000000)>>24;

  return (sfd);
}


/*****************************************************************************
 kills (disconnects) a socket

 returns SUCCESS if it worked or

 ERROR_KILL if it couldn't be disconnected
******************************************************************************/

int tcpKillConn (int fd)
{
  int retcode;

  retcode = close (fd);
  if (retcode==-1) return (ERROR_KILL);
  else return (SUCCESS);
}



/*****************************************************************************
 writes out buffer of size bufsize to an open file descriptor (a socket)

 returns number of bytes written or

 ERROR_WRITEFAILED - write failed
******************************************************************************/

int tcpWriteBuffer (int fd, char *buffer, size_t bufsize)
{
  int retcode;
  
  retcode=write (fd, buffer, bufsize);

  if (retcode==-1) {
    return (ERROR_WRITEFAILED);
  }
  else return (retcode);
}


/*****************************************************************************
 synchronous I/O multiplexer - detects if there's stuff waiting using select
 
 returns DATA if there's data, or NODATA if there's none

******************************************************************************/

int tcpDataWaiting (int sfd)
{
  fd_set fds;
  struct timeval tv;

  bzero (&tv, sizeof (struct timeval));
  tv.tv_usec = 1;

  FD_ZERO (&fds);

  FD_SET (sfd, &fds);
  while ((select (sfd+1, &fds, NULL, NULL, &tv))==-1); /* make sure select */
                                                       /* works            */

  if (FD_ISSET (sfd, &fds)) return (DATA);
  else return (NODATA);
}



/******************************************************************************
 reads bytes from a socket file descriptor, putting them into the buffer

 returns number of bytes read, or

 ERROR_HANGUP if the socket has been disconnected

******************************************************************************/

int tcpReadBuffer (int fd, char *buffer, int bufsize)
{
  int count;

  count=read (fd, buffer, bufsize);
  if (count==0) {
    close (fd);
    return (ERROR_HANGUP);
  } else if (count==-1) {
    return (ERROR_READ); 
  }
  else return (count);
}


Steve Richardson 2000-07-06
Table of Contents

[PDF] [Whole document in PDF 1.9MB]

[more photos and information]

 
Page last modified:
Copyright © 1993-2000 prefect - All Rights Reserved.