Simple TCP & UDP socket library for EthernetInterface
Dependents: SimpleSocketExamples SimpleSocketExamples Data_collection_tcpip
Revision 0:cbc8e17f7043, committed 2013-02-04
- Comitter:
- yamaguch
- Date:
- Mon Feb 04 08:45:18 2013 +0000
- Commit message:
- modified to use EthernetInterface
Changed in this revision
SimpleSocket.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r 000000000000 -r cbc8e17f7043 SimpleSocket.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SimpleSocket.h Mon Feb 04 08:45:18 2013 +0000 @@ -0,0 +1,274 @@ +#ifndef SIMPLE_SOCKET_H +#define SIMPLE_SOCKET_H + +#include "mbed.h" +#include "EthernetInterface.h" +#include <stdarg.h> + +/** + * client socket class for communication endpoint + */ +class ClientSocket { + friend class ServerSocket; + +public: + ClientSocket(char *hostname, int port) : preread(-1), timeout(1.5) { + if (EthernetInterface::getIPAddress() == NULL) { + EthernetInterface::init(); + EthernetInterface::connect(); + } + sock = new TCPSocketConnection(); + sock->connect(hostname, port); + sock->set_blocking(false, (int) (timeout * 1000)); + } + + ClientSocket(TCPSocketConnection *sock) : sock(sock), preread(-1), timeout(1.5) { + sock->set_blocking(false, (int) (timeout * 1000)); + } + + ~ClientSocket() { + // do NOT close in the destructor. + } + + void setTimeout(float timeout) { + sock->set_blocking(false, (int) (timeout * 1000)); + this->timeout = timeout; + } + + bool available() { + if (preread == -1) { + char c; + sock->set_blocking(false, 0); + if (sock->receive((char *) &c, 1) <= 0) { + sock->set_blocking(false, (int) (timeout * 1000)); + return false; + } + preread = c & 255; + sock->set_blocking(false, (int) (timeout * 1000)); + } + + return true; + } + + int read() { + char c; + if (preread != -1) { + c = (char) preread; + preread = -1; + } else { + if (sock->receive((char *) &c, 1) <= 0) + return -1; + } + + return c & 255; + } + + int read(char *buf, int size) { + if (size <= 0) + return 0; + + int nread = 0; + if (preread != -1) { + nread = 1; + *buf++ = (char) preread; + preread = -1; + size--; + } + + if (size > 0) { + size = sock->receive_all(buf, size - 1); + if (size > 0) + nread += size; + } + + return (nread > 0) ? nread : -1; + } + + int scanf(const char *format, ...) { + va_list argp; + va_start(argp, format); + char buf[256]; + + int len = read(buf, sizeof(buf) - 1); + if (len <= 0) + return 0; + buf[len] = '\0'; + + int ret = vsscanf(buf, format, argp); + va_end(argp); + + return ret; + } + + int write(char c) { + return sock->send_all(&c, 1); + } + + int write(char *buf, int size) { + return sock->send_all(buf, size); + } + + int printf(const char *format, ...) { + va_list argp; + va_start(argp, format); + char buf[256]; + + int len = vsnprintf(buf, sizeof(buf), format, argp); + va_end(argp); + + return write(buf, len); + } + + void close() { + if (sock) { + sock->close(); + delete sock; + sock = 0; + } + } + + bool connected() { + return sock && sock->is_connected(); + } + + operator bool() { + return connected(); + } + +private: + TCPSocketConnection *sock; + int preread; + float timeout; +}; + +/** +* server socket class for handling incoming communication requests +*/ +class ServerSocket { +public: + ServerSocket(int port) { + if (EthernetInterface::getIPAddress() == NULL) { + EthernetInterface::init(); + EthernetInterface::connect(); + } + ssock.bind(port); + ssock.listen(); + } + + ClientSocket accept() { + TCPSocketConnection *sock = new TCPSocketConnection(); + ssock.accept(*sock); + + return ClientSocket(sock); + } + +private: + TCPSocketServer ssock; +}; + +/** + * class for handling datagram + */ +class DatagramSocket { +public: + DatagramSocket(int port = 0, int bufsize = 512) : bufsize(bufsize) { + if (EthernetInterface::getIPAddress() == NULL) { + EthernetInterface::init(); + EthernetInterface::connect(); + } + buf = new char[bufsize + 1]; + usock.init(); + usock.bind(port); + usock.set_blocking(false, 1500); + } + + DatagramSocket(Endpoint& local, int bufsize = 512) : bufsize(bufsize) { + if (EthernetInterface::getIPAddress() == NULL) { + EthernetInterface::init(); + EthernetInterface::connect(); + } + buf = new char[bufsize + 1]; + usock.init(); + usock.bind(local.get_port()); + usock.set_blocking(false, 1500); + } + + ~DatagramSocket() { + delete[] buf; + } + + void setTimeout(float timeout = 1.5) { + usock.set_blocking(false, (int) (timeout * 1000)); + } + + int write(char *buf, int length) { + if (length > bufsize) length = bufsize; + this->length = length; + memcpy(this->buf, buf, length); + + return length; + } + + int printf(const char* format, ...) { + va_list argp; + va_start(argp, format); + int len = vsnprintf(buf, bufsize, format, argp); + va_end(argp); + if (len > 0) + length = len; + + return len; + } + + void send(const char *host, int port) { + Endpoint remote; + remote.reset_address(); + remote.set_address(host, port); + usock.sendTo(remote, buf, length); + } + + void send(Endpoint& remote) { + usock.sendTo(remote, buf, length); + } + + int receive(char *host = 0, int *port = 0) { + Endpoint remote; + length = usock.receiveFrom(remote, buf, bufsize); + if (length > 0) { + if (host) strcpy(host, remote.get_address()); + if (port) *port = remote.get_port(); + } + + return length; + } + + int receive(Endpoint& remote) { + return usock.receiveFrom(remote, buf, bufsize); + } + + int read(char *buf, int size) { + int len = length < size ? length : size; + if (len > 0) + memcpy(buf, this->buf, len); + + return len; + } + + int scanf(const char* format, ...) { + va_list argp; + va_start(argp, format); + buf[length] = '\0'; + int ret = vsscanf(buf, format, argp); + va_end(argp); + + return ret; + } + +private: + char *buf; + int bufsize; + int length; + UDPSocket usock; +}; + +#endif \ No newline at end of file