|
|
#ifndef SOCK_H_INCLUDED #define SOCK_H_INCLUDED #ifdef WIN32 #include <winsock.h> #else // WIN32 #include <sys/types.h> #include <sys/socket.h> #include <sys/time.h> #include <unistd.h> #include <netinet/in.h> #include <arpa/inet.h> typedef struct sockaddr_in SOCKADDR_IN; typedef int SOCKET; #endif // WIN32 class CTcpSock; /** * The TCallBack type is used for all callbacks whenever the @ref CTcpSock * changes state. * * @param sock pointer to the socket object that changed state. */ typedef void TCallBack(CTcpSock* sock); /** * Lookup an address consisting of host name (or IP) and port number. * * @param host The hostname or IP address in dot notaion, e.g. "192.168.0.1" * @param port port number * @param pAdr pointer to a variable for storing the result * @return zero on success */ int get_address(const char* host, int port, SOCKADDR_IN* pAdr); /** * Retrieve the error code of the last failed socket operation. * * @return error code */ int getSocketError(); /** * The CTcpSock represents a socket used for asynchronous operation. * * When a CTcpSock has been created, it can be registered with an * @ref CEventLoop which passes 'events' from a select system * call to the socket object, whenever data arrives or the socket * is ready to recieve more data for writing. * * Handling of the events is implemented as a finite state machine. * Callbacks can be registered for whenever the socket changes state. * Callback function pointers are stored in the m_cb* member variables. * * @short This class represents an asynchronous TCP socket. * @see CEventLoop * @author Pelle Johnsen */ class CTcpSock { public: /** * Constructor which initializes datamembers. */ CTcpSock(void); /** * Destructor which automatically closes the socket if it has * been connected. */ ~CTcpSock(void); /** * Creates the socket, i.e. gets a socket handle ( @ref m_sock ). * * @return zero on success */ int create(void); /** * Closes the socket if it has been connected. It is safe to call * close even if the socket wasn't created or connected. * * @return zero on success */ int close(void); /** * Start connecting the socket to a remote peer. When the connect * completes the @ref m_cbConnectOk callback will be called. * * @param name address (host, port) of the remote peer * @return zero or EINPROGRESS on success */ int connect(SOCKADDR_IN* name); /** * Start sending a buffer to the remote peer. When all bytes have * been send the @ref m_cbSendOk callback will be called. * * @param buf pointer to the buffer * @param len number of bytes to send * @return number of bytes sent so far */ int send(const char* buf, int len); /** * Start sending a zero terminated string. When the whole string has * been sent the @ref m_cbSendOk callback will be called. * * @param str the string to send * @return number of bytes sent so far */ int sendString(const char* str); /** * Start receiving a buffer. When the desired number of bytes have * been read or the remote end has closed the socket, the * @ref m_cbRecvBufOk callback will be called. * * @param buf pointer to buffer for receiving data * @param len number of bytes to receive * @return zero on success */ int recvBuf(char* buf, int len); /** * Start reading a line from the socket. When a full line have * been read or the remote end has closed the socket, the * @ref m_cbReadLineOk callback will be called. * * @param buf pointer to buffer for receiving data * @param max_len maximum number of bytes to read. * @return zero on success */ int readLine(char* buf, int max_len); /** * Sets fd_sets for this socket depending on it's state. The fd_sets * are used by a @ref CEventLoop for the select system call. Basically * this socket indicates to the EventLoop if it is currently interested * in read, write or exception events. * * @param rfds read fd_set * @param wfds write fd_set * @param efds exception fd_set * @return zero on success */ int setFdSets(fd_set* rfds, fd_set* wfds, fd_set* efds); /** * Checks fd_sets for this socket after the @ref CEventLoop returns * from the select system call, to see if there was any events for * this socket. If an event arrived @ref processEvent is called. * Before returning to the EventLoop any new internal events are * handled by calling the appropriate callback. * * @param rfds read fd_set * @param wfds write fd_set * @param efds exception fd_set * @return zero on success */ int checkFdSets(fd_set* rfds, fd_set* wfds, fd_set* efds); /** * Ask the socket to delete itself, just before returning to the * EventLoop. This allows for 'nested' callbacks that needs * to delete the socket object. */ void deleteSock(void); /** * The socket handle (i.e. file descriptor on UNIX) */ SOCKET m_sock; /** * This is a pointer to some arbitrary context you can assign * to the socket. This is useful if you have one set of callback * functions which handle multiple sockets. They can use the context * data to figure out where the particular socket 'belong' */ void* m_context; /** * Callback for when the socket has succesfully connected to the * remote peer. */ TCallBack* m_cbConnectOk; /** * Callback for when a send or sendString has completed. */ TCallBack* m_cbSendOk; /** * Callback for when a line has been read from the socket. */ TCallBack* m_cbReadLineOk; /** * Callback for when a buffer has been received. */ TCallBack* m_cbRecvBufOk; /** * Pointer to the buffer being written ( @ref send , * @ref sendString ). */ const char* m_wbuf; /** * Number of bytes to be sent. */ int m_wlen; /** * Number of bytes actually sent (so far). */ int m_sent; /** * Pointer to the buffer being read to ( @ref readLine , * @ref recvBuf ). */ char* m_rbuf; /** * Number of bytes to be read */ int m_rlen; /** * Number of bytes actually read (so far). */ int m_read; /** * Non-zero if the socket has been closed at the remote end. */ int m_eof; protected: /** * The different states of the socket */ enum ESockStates { start, created, connecting, ready, sending, recievingBuf, readingLine, closed }; ESockStates m_state; /** * Types of events received from the EventLoop */ enum EEvents { read = 1, write = 2, except = 4 }; /** * Internal events used to do callbacks and delete the socket * before returning to the EventLoop, if needed. */ enum ESockInternalEvents { noEvent, connectOk, sendOk, readLineOk, recvBufOk, deleteEvent }; ESockInternalEvents m_intStatus; /** * Processes an event received from the EventLoop. Takes the * appropriate action depending on the current state ( @ref m_state ). * * @param event type of event: read, write, exception * @return zero on success */ int processEvent(int event); /** * Called every time data arrives, when reading a line */ void readLineLoop(void); /** * Called every time data arrives, when reading to a buffer */ void recvBufLoop(void); }; #endif // SOCK_H_INCLUDED
Generated by: pelle@pjws.localdomain on Wed Mar 14 12:09:22 2001, using kdoc 2.0a52. |