|
Next: VHDL Code
Up: MIDI Controller
Previous: TCP/IP Server Library Header,
  Contents
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
[Whole document in PDF 1.9MB]
[more photos and information]
|