- Allowed write buffers to become very large in asynnet. Thus in order to allow for the transfer of large images. tested ub to 2kx2k, 16MB - Handle lack of space in the write buffer more gracefully: just skip the image
219 lines
8.9 KiB
C
219 lines
8.9 KiB
C
/**
|
|
* Asynchronous networking for SICS and other programs. This module centrally manages
|
|
* a number of network connections for a client program. It is a layer between the
|
|
* program and the network which manages non blocking network I/O. To this purpose, the
|
|
* client program has to call ANETprocess at convenient intervals. This module
|
|
* has a couple of features:
|
|
* - Connections are abstracted to handles which are guaranteed to be unique
|
|
* rather then socket numbers. Socket numbers may be reused by the OS.
|
|
* - This module allows upper level code to figure out if a connection is still
|
|
* connected or not.
|
|
* - This module introduces a buffer layer between the socket and the application.
|
|
* Thus the upper layer does not have to worry much about I/O blocking. This
|
|
* is taken care of by this module both for reading and writing.
|
|
* - All I/O is non blocking.
|
|
* - This module can detect if a client is hanging and close the connection then.
|
|
* Hanging is detected by not being able to write to the client for some period
|
|
* of time.
|
|
*
|
|
* copyright: see file COPYRIGHT
|
|
*
|
|
* Mark Koennecke, January 2009
|
|
*/
|
|
#ifndef ASYNNET_H_
|
|
#define ASYNNET_H_
|
|
/*=================== error codes ========================================*/
|
|
#define ANETOK 1
|
|
#define ANETDISCONNECTED -10000
|
|
#define ANETWRITEBUFFERFULL -10001
|
|
#define ANETTIMEOUT -10002
|
|
#define ANETOPENFAIL -10003
|
|
#define ANETSOCKERROR -10004
|
|
#define ANETMEM -10005
|
|
#define ANETOUTOFSOCKETS -10006
|
|
/*================== log levels ==========================================*/
|
|
#define ANETNONE 0
|
|
#define ANETERROR 1
|
|
#define ANETIO 2
|
|
#define ANETCON 3
|
|
/*================== callback functions ==================================*/
|
|
/**
|
|
* \brief Callback called when a connection has been accepted on a
|
|
* port or data is ready.
|
|
* \param handle The handle of the new network connection
|
|
* \return 1 if the new connection can be accepted or 0 if not.
|
|
* Same for data.
|
|
*/
|
|
typedef int (*ANETcallback) (int handle, void *userData);
|
|
/**
|
|
* \brief a callback which is called in order to determine if a
|
|
* a terminator is present in the data.
|
|
* \param data The data to inspect
|
|
* \param length The length of the data to inspect
|
|
* \param userData An opaque pointer passed through to this
|
|
* function
|
|
* \return -1 when no terminator is in the data, an integer pointing
|
|
* to after the terminator in data (in bytes).
|
|
*/
|
|
typedef int (*ANETtermCallback) (void *data, int length, void *userData);
|
|
/**
|
|
* \brief a callback function for waiting on some event.
|
|
* This is typically called to do something else while waiting
|
|
* for data to arrive. It can also return a negative return value,
|
|
* which will effectively implement a timeout.
|
|
* \param userData An opaque pointer passed through to this callback
|
|
* \return 1 to continue waiting, -1 for a timeout.
|
|
*/
|
|
typedef int (*ANETwait) (void *userData);
|
|
/**
|
|
* \brief callback to log events in ANET
|
|
* \param level The level of the logging message
|
|
* \param txt The logging data
|
|
* \param userData An opaque pointer passed through to ANETlog
|
|
*/
|
|
typedef void (*ANETlog) (int level, char *txt, void *userData);
|
|
/**
|
|
* \brief a callback for killing userdata associated with a read callback.
|
|
* This is called in ANETclose, if defined.
|
|
* \param userData The user data to kill.
|
|
*/
|
|
typedef void (*ANETkill) (void *userData);
|
|
/*===================== open/close functions =============================*/
|
|
/**
|
|
* * \brief open a server port
|
|
* \param iPort The port number at which to listen for
|
|
* connections.
|
|
* \param cb A callback which will be called whenever a new connection
|
|
* has been accepted on this port.
|
|
* \prama userData An opaque pointer to be passed as an argument to the
|
|
* callback function.
|
|
* \return A handle for the server port or a negative error code.
|
|
*/
|
|
int ANETopenServerPort(int iPort, ANETcallback cb, void *userData);
|
|
/**
|
|
* \brief open a client connection to a server.
|
|
* \param name the computer name of the server
|
|
* \param iPort The port number at which the server is listening
|
|
* \return A handle to the open port or a negative error code.
|
|
*/
|
|
int ANETconnect(char *name, int iPort);
|
|
/**
|
|
* \brief register a socket to be managed by this module. The socket
|
|
* may have been obtained by any means.
|
|
* \param socket The file descriptor of the socket
|
|
* \return A handle to use for this socket later on.
|
|
*/
|
|
int ANETregisterSocket(int socket);
|
|
/**
|
|
* \brief close a connection
|
|
* \param handle The handle of the connection
|
|
*/
|
|
void ANETclose(int handle);
|
|
/**
|
|
* \brief This function drives I/O processing, i.e. reading and writing.
|
|
* This has to be called by the client of this module at regular intervalls.
|
|
*/
|
|
void ANETprocess(void);
|
|
/**
|
|
* \brief tests if a handle is still a valid connection
|
|
* \param handle The handle to test.
|
|
* \return 1 if this is still a connected socket, 0 else.
|
|
*/
|
|
int ANETvalidHandle(int handle);
|
|
/**
|
|
* \brief figure out to which host we are connected.
|
|
* \param handle The connection handle
|
|
* \param hostname a buffer to copy the hostname into
|
|
* \param hostNameLen the length of the hostname buffer
|
|
* \return 1 on success, a negative error code else.
|
|
*/
|
|
int ANETinfo(int handle, char *hostname, int hostNameLen);
|
|
/*=================== I/O functions ===========================================
|
|
* For reading there are possibilities:
|
|
* - Raw reading happens through the combination of
|
|
* ANETread and ANETreadConsume.
|
|
* - Another way for raw reading is to register a read callback which is
|
|
* called anytime new data arrives.
|
|
* - The usual case is to wait for a line of terminated command input. This is
|
|
* done through ANETreadTillterm.
|
|
* ==========================================================================*/
|
|
/**
|
|
* \brief write to the network
|
|
* \param handle The handle for the connection
|
|
* \param buffer A pointer to the data to write
|
|
* \param count The number of bytes to write.
|
|
* \return 1 on success, 0 on failure
|
|
*/
|
|
int ANETwrite(int handle, void *buffer, int count);
|
|
/**
|
|
* \brief Test if the buffer can be written to the network
|
|
* \param handle The handle for the connection
|
|
* \param buffer A pointer to the data to write
|
|
* \param count The number of bytes to write.
|
|
* \return 1 when possible, 0 when buffer overrun
|
|
*/
|
|
int ANETcanWrite(int handle, void *buffer, int count);
|
|
/**
|
|
* \brief copy at max bufferLength bytes into buffer. The data is not deleted from
|
|
* the read buffer yet.
|
|
* \param handle The handle of the connection to read from
|
|
* \param buffer a pointer to an area for holding the data
|
|
* \param bufferLength The maximum number of bytes which can be copied into
|
|
* the buffer.
|
|
* \return The number of bytes copied. Can be 0 if no data is available. On
|
|
* errors a negative error code is returned.
|
|
*/
|
|
int ANETread(int handle, void *buffer, int bufferLength);
|
|
/**
|
|
* \brief Get a pointer to the data which has been read up to now.
|
|
* Do not mess with the data!! Else the result may be badly defined!
|
|
* \param handle The handle for the connection
|
|
* \param length will be set to the length of the data read so far.
|
|
* \return NULL when the socket is disconnected, a pointer else.
|
|
*/
|
|
void *ANETreadPtr(int handle, int *length);
|
|
/**
|
|
* \brief remove count bytes from the read buffer.
|
|
* \param handle The handle for the connection.
|
|
* \param count The number of bytes which can be removed from the
|
|
* read buffer.
|
|
*/
|
|
void ANETreadConsume(int handle, int count);
|
|
/**
|
|
* \brief set a callback to be called when data is available at the port.
|
|
* \param handle The handle of the connection
|
|
* \param cb The callback function to call
|
|
* \param userData An opaque pointer passed on as a parameter to the
|
|
* callback function.
|
|
*/
|
|
void ANETsetReadCallback(int handle, ANETcallback cb, void *userData,
|
|
ANETkill killUser);
|
|
/**
|
|
* \brief wait for terminated data to arrive.
|
|
* \param handle The connection handle to read from
|
|
* \param tcb a callback function which determines if a terminator is in the
|
|
* data.
|
|
* \param termData An opaque data pointer passed on to tcb
|
|
* \param wcb A callback function called while waiting for data
|
|
* to arrive.
|
|
* \param waitData An opaque pointer passed on to wcb
|
|
* \param buffer A newly allocated buffer holding the data as read
|
|
* including the terminator.
|
|
* \return 1 on success, a negative error code else.
|
|
*/
|
|
int ANETreadTillTerm(int handle,
|
|
ANETtermCallback tcb, void *termData,
|
|
ANETwait wcb, void *waitData, char **buffer);
|
|
/**
|
|
* Note to Markus: suitable callbacks for the standard case: waiting for \n and
|
|
* TaskYield for waiting to a timeout will become part of nread.h, .c.
|
|
*/
|
|
/*========================== system ====================================*/
|
|
/**
|
|
* \brief install a logging function
|
|
* \param lcb The logging function to install
|
|
* \param userData An opaque pointer with data for lcb
|
|
*/
|
|
void ANETsetLog(ANETlog lcb, void *userData);
|
|
#endif /*ASYNNET_H_ */
|