|
Projects
Spring 2012 Older Courses Fall 2011 Spring 2011 Fall 2010 Spring 2010 Fall 2009 Spring 2009
Fall 2008
Spring 2008
Fall 2007 HOWTOs |
Udpsendudpsend.h:
/****************************************************************************************
* udpsend.h v1.0 by Kareem Abu-Zahra (kareem_net@hotmail.com)
*
* Contains definitions and function protoypes for udpsend.c. Udpsend is meant
* to be used as a client to any number of udp servers (services). It will
* also wait for an ACK from the server to insure the server is actually up.
*
*
* Function: udpinit(uctx *ctx, SERVICE)
*
* Description: Initializes a context with a SERVICE that is defined
* in the services.h file.
*
* Returns: 0 on Success, a negative number on Error.
*
*
*
* Function: udpsend(uctx *ctx, char *msg)
*
* Description: Sends a message to the service defined by the ctx.
*
* Returns: A negative number on Error or Server Timeout
* On success, returns the number of characters transmitted.
*
* Function: udpclose(uctx *ctx)
*
* Description: Closes a context (closes the socket).
*
* Returns: 0 on Success
*
*
* Example:
*
* uctx ctx;
*
* udpinit(&ctx, PROLITE);
*
* udpsend(&ctx, "message1");
* .
* .
* .
* udpsend(&ctx, "message2");
*
* udpclose(&ctx);
*
*/
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>
#include "services.h"
#ifndef __UDPSEND_H
#define __UDPSEND_H
#define SERV_HOST_ADDR "127.0.0.1"
#define getport(service) \
service ## _PORT
#define getlimit(service) \
service ## _LIMIT
/* ERROR DEFINITIONS */
#define ERROR_SERVER_SOCKET -1;
#define ERROR_CTX_CLOSED -2;
#define ERROR_SEND -3;
#define ERROR_NO_ACK -4;
#define ERROR_BAD_ACK -5;
#define ERROR_SELECT -6;
/* CTX STATES */
#define CTX_OPEN 0xdeadbeef
#define CTX_CLOSED 0x00000000
typedef struct {
int port;
int send_max;
int serv_sock;
unsigned int state;
struct sockaddr_in serv_addr;
} uctx;
//typedef struct uctx uctx;
#define min(a, b) (((a)<(b))?(a):(b))
#define udpinit(ctx, service) \
kudpinit(ctx, service ## _PORT, service ## _LIMIT);
#ifdef __cplusplus
extern "C" {
#endif
int kudpinit(uctx *ctx, int port, int send_max);
int udpsend(uctx *ctx, char *msg);
int udpclose(uctx *ctx);
#ifdef __cplusplus
}
#endif
#endif
udpsend.c:
//#include <fcntl.h> /* File control definitions */
//#include <errno.h> /* Error number definitions */
//#include <termios.h> /* POSIX terminal control definitions */
#include "udpsend.h"
#include <unistd.h>
#include <strings.h>
#include <string.h>
//#include <sys/socket.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int kudpinit(uctx *ctx, int port, int send_max)
{
int len;
ctx->port = port;
ctx->send_max = send_max;
/* Open port to server */
bzero((char *) &ctx->serv_addr, sizeof(ctx->serv_addr));
ctx->serv_addr.sin_family = AF_INET;
ctx->serv_addr.sin_addr.s_addr = inet_addr(SERV_HOST_ADDR);
ctx->serv_addr.sin_port = htons(ctx->port);
if ((ctx->serv_sock = socket(AF_INET, SOCK_DGRAM, 0)) <0) {
return ERROR_SERVER_SOCKET;
}
ctx->state = CTX_OPEN;
return 0;
}
int udpsend(uctx *ctx, char *msg)
{
int r;
char c;
fd_set fds;
struct timeval tv;
int len;
printf("in udpsend to send %s\n", msg);
if (ctx->state != CTX_OPEN)
return ERROR_CTX_CLOSED;
if ((r = sendto(ctx->serv_sock, msg, min(ctx->send_max, strlen(msg)), 0, (struct sockaddr *)&ctx->serv_addr, sizeof(ctx->serv_addr))) < 0)
return ERROR_SEND;
//wait for ack, we are already bound on our port
FD_ZERO(&fds);
FD_SET(ctx->serv_sock, &fds);
tv.tv_sec = 1;
// tv.tv_usec = 300000;
tv.tv_usec = 0;
r = select(ctx->serv_sock + 1, &fds, NULL, NULL, &tv);
printf("select returned: %d\n", r);
if (r == -1)
{
return ERROR_SELECT;
} else {
if (r) {
if (r = recvfrom(ctx->serv_sock, (char *)&c, 1, 0, NULL, NULL) < 1)
return r; //r could be 0 (shutdown from peer) or -1 (error)
if (c = 0x01)
return 0;
else
return ERROR_BAD_ACK;
} else {
return ERROR_NO_ACK;
}
}
}
int udpclose(uctx *ctx)
{
close(ctx->serv_sock);
ctx->state = CTX_CLOSED;
return 0;
}
services.h: /**************************************************************************************** * services.h v1.0 by Kareem Abu-Zahra (kareem_net@hotmail.com) * * This file is included by the server and client code. A service is * defined by a port and the maximum amount of characters it can * handle. Example: * * #define PROLITE_PORT 9000 * #define PROLITE_LIMIT 490 */ #ifndef __SERVICES_H #define __SERVICES_H /* PORT DEFINITIONS */ #define PROLITE_PORT 9000 #define STEERING_PORT 9001 /* SEND_MAX DEFINITIONS */ #define PROLITE_LIMIT 490 #define STEERING_LIMIT 490 #endif |