Simple TCP & UDP socket library for EthernetInterface

Dependents:   SimpleSocketExamples SimpleSocketExamples Data_collection_tcpip

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SimpleSocket.h Source File

SimpleSocket.h

00001 #ifndef SIMPLE_SOCKET_H
00002 #define SIMPLE_SOCKET_H
00003 
00004 #include "mbed.h"
00005 #include "EthernetInterface.h"
00006 #include <stdarg.h>
00007 
00008 /**
00009  * client socket class for communication endpoint
00010  */
00011 class ClientSocket {
00012     friend class ServerSocket;
00013 
00014 public:
00015     ClientSocket(char *hostname, int port) : preread(-1), timeout(1.5) {
00016         if (EthernetInterface::getIPAddress() == NULL) {
00017             EthernetInterface::init();
00018             EthernetInterface::connect();
00019         }
00020         sock = new TCPSocketConnection();
00021         sock->connect(hostname, port);
00022         sock->set_blocking(false, (int) (timeout * 1000));
00023     }
00024 
00025     ClientSocket(TCPSocketConnection *sock) : sock(sock), preread(-1), timeout(1.5) {
00026         sock->set_blocking(false, (int) (timeout * 1000));
00027     }
00028 
00029     ~ClientSocket() {
00030         // do NOT close in the destructor.
00031     }
00032 
00033     void setTimeout(float timeout) {
00034         sock->set_blocking(false, (int) (timeout * 1000));
00035         this->timeout = timeout;
00036     }
00037 
00038     bool available() {
00039         if (preread == -1) {
00040             char c;
00041             sock->set_blocking(false, 0);
00042             if (sock->receive((char *) &c, 1) <= 0) {
00043                 sock->set_blocking(false, (int) (timeout * 1000));
00044                 return false;
00045             }
00046             preread = c & 255;
00047             sock->set_blocking(false, (int) (timeout * 1000));
00048         }
00049         
00050         return true;
00051     }
00052 
00053     int read() {
00054         char c;
00055         if (preread != -1) {
00056             c = (char) preread;
00057             preread = -1;
00058         } else {
00059             if (sock->receive((char *) &c, 1) <= 0)
00060                 return -1;
00061         }
00062         
00063         return c & 255;
00064     }
00065 
00066     int read(char *buf, int size) {
00067         if (size <= 0)
00068             return 0;
00069 
00070         int nread = 0;
00071         if (preread != -1) {
00072             nread = 1;
00073             *buf++ = (char) preread;
00074             preread = -1;
00075             size--;
00076         }
00077 
00078         if (size > 0) {
00079             size = sock->receive_all(buf, size - 1);
00080             if (size > 0)
00081                 nread += size;
00082         }
00083 
00084         return (nread > 0) ? nread : -1;
00085     }
00086 
00087     int scanf(const char *format, ...) {
00088         va_list argp;
00089         va_start(argp, format);
00090         char buf[256];
00091 
00092         int len = read(buf, sizeof(buf) - 1);
00093         if (len <= 0)
00094             return 0;
00095         buf[len] = '\0';
00096 
00097         int ret = vsscanf(buf, format, argp);
00098         va_end(argp);
00099         
00100         return ret;
00101     }
00102 
00103     int write(char c) {
00104         return sock->send_all(&c, 1);
00105     }
00106 
00107     int write(char *buf, int size) {
00108         return sock->send_all(buf, size);
00109     }
00110 
00111     int printf(const char *format, ...) {
00112         va_list argp;
00113         va_start(argp, format);
00114         char buf[256];
00115 
00116         int len = vsnprintf(buf, sizeof(buf), format, argp);
00117         va_end(argp);
00118         
00119         return write(buf, len);
00120     }
00121 
00122     void close() {
00123         if (sock) {
00124             sock->close();
00125             delete sock;
00126             sock = 0;
00127         }
00128     }
00129 
00130     bool connected() {
00131         return sock && sock->is_connected();
00132     }
00133 
00134     operator bool() {
00135         return connected();
00136     }
00137 
00138 private:
00139     TCPSocketConnection *sock;
00140     int preread;
00141     float timeout;
00142 };
00143 
00144 /**
00145 * server socket class for handling incoming communication requests
00146 */
00147 class ServerSocket {
00148 public:
00149     ServerSocket(int port) {
00150         if (EthernetInterface::getIPAddress() == NULL) {
00151             EthernetInterface::init();
00152             EthernetInterface::connect();
00153         }
00154         ssock.bind(port);
00155         ssock.listen();
00156     }
00157 
00158     ClientSocket accept() {
00159         TCPSocketConnection *sock = new TCPSocketConnection();
00160         ssock.accept(*sock);
00161         
00162         return ClientSocket(sock);
00163     }
00164 
00165 private:
00166     TCPSocketServer ssock;
00167 };
00168 
00169 /**
00170  * class for handling datagram
00171  */
00172 class DatagramSocket {
00173 public:
00174     DatagramSocket(int port = 0, int bufsize = 512) : bufsize(bufsize) {
00175         if (EthernetInterface::getIPAddress() == NULL) {
00176             EthernetInterface::init();
00177             EthernetInterface::connect();
00178         }
00179         buf = new char[bufsize + 1];
00180         usock.init();
00181         usock.bind(port);
00182         usock.set_blocking(false, 1500);
00183     }
00184 
00185     DatagramSocket(Endpoint& local, int bufsize = 512) : bufsize(bufsize) {
00186         if (EthernetInterface::getIPAddress() == NULL) {
00187             EthernetInterface::init();
00188             EthernetInterface::connect();
00189         }
00190         buf = new char[bufsize + 1];
00191         usock.init();
00192         usock.bind(local.get_port());
00193         usock.set_blocking(false, 1500);
00194     }
00195 
00196     ~DatagramSocket() {
00197         delete[] buf;
00198     }
00199 
00200     void setTimeout(float timeout = 1.5) {
00201         usock.set_blocking(false, (int) (timeout * 1000));
00202     }
00203     
00204     int write(char *buf, int length) {
00205         if (length > bufsize) length = bufsize;
00206         this->length = length;
00207         memcpy(this->buf, buf, length);
00208         
00209         return length;
00210     }
00211 
00212     int printf(const char* format, ...) {
00213         va_list argp;
00214         va_start(argp, format);
00215         int len = vsnprintf(buf, bufsize, format, argp);
00216         va_end(argp);
00217         if (len > 0)
00218             length = len;
00219             
00220         return len;
00221     }
00222 
00223     void send(const char *host, int port) {
00224         Endpoint remote;
00225         remote.reset_address();
00226         remote.set_address(host, port);
00227         usock.sendTo(remote, buf, length);
00228     }
00229 
00230     void send(Endpoint& remote) {
00231         usock.sendTo(remote, buf, length);
00232     }
00233 
00234     int receive(char *host = 0, int *port = 0) {
00235         Endpoint remote;
00236         length = usock.receiveFrom(remote, buf, bufsize);
00237         if (length > 0) {
00238             if (host) strcpy(host, remote.get_address());
00239             if (port) *port = remote.get_port();
00240         }
00241         
00242         return length;
00243     }
00244 
00245     int receive(Endpoint& remote) {
00246         return usock.receiveFrom(remote, buf, bufsize);
00247     }
00248 
00249     int read(char *buf, int size) {
00250         int len = length < size ? length : size;
00251         if (len > 0)
00252             memcpy(buf, this->buf, len);
00253             
00254         return len;
00255     }
00256 
00257     int scanf(const char* format, ...) {
00258         va_list argp;
00259         va_start(argp, format);
00260         buf[length] = '\0';
00261         int ret = vsscanf(buf, format, argp);
00262         va_end(argp);
00263         
00264         return ret;
00265     }
00266 
00267 private:
00268     char *buf;
00269     int bufsize;
00270     int length;
00271     UDPSocket usock;
00272 };
00273 
00274 #endif