Simple TCP & UDP socket library for EthernetInterface

Dependents:   SimpleSocketExamples SimpleSocketExamples Data_collection_tcpip

Committer:
yamaguch
Date:
Mon Feb 04 08:45:18 2013 +0000
Revision:
0:cbc8e17f7043
modified to use EthernetInterface

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yamaguch 0:cbc8e17f7043 1 #ifndef SIMPLE_SOCKET_H
yamaguch 0:cbc8e17f7043 2 #define SIMPLE_SOCKET_H
yamaguch 0:cbc8e17f7043 3
yamaguch 0:cbc8e17f7043 4 #include "mbed.h"
yamaguch 0:cbc8e17f7043 5 #include "EthernetInterface.h"
yamaguch 0:cbc8e17f7043 6 #include <stdarg.h>
yamaguch 0:cbc8e17f7043 7
yamaguch 0:cbc8e17f7043 8 /**
yamaguch 0:cbc8e17f7043 9 * client socket class for communication endpoint
yamaguch 0:cbc8e17f7043 10 */
yamaguch 0:cbc8e17f7043 11 class ClientSocket {
yamaguch 0:cbc8e17f7043 12 friend class ServerSocket;
yamaguch 0:cbc8e17f7043 13
yamaguch 0:cbc8e17f7043 14 public:
yamaguch 0:cbc8e17f7043 15 ClientSocket(char *hostname, int port) : preread(-1), timeout(1.5) {
yamaguch 0:cbc8e17f7043 16 if (EthernetInterface::getIPAddress() == NULL) {
yamaguch 0:cbc8e17f7043 17 EthernetInterface::init();
yamaguch 0:cbc8e17f7043 18 EthernetInterface::connect();
yamaguch 0:cbc8e17f7043 19 }
yamaguch 0:cbc8e17f7043 20 sock = new TCPSocketConnection();
yamaguch 0:cbc8e17f7043 21 sock->connect(hostname, port);
yamaguch 0:cbc8e17f7043 22 sock->set_blocking(false, (int) (timeout * 1000));
yamaguch 0:cbc8e17f7043 23 }
yamaguch 0:cbc8e17f7043 24
yamaguch 0:cbc8e17f7043 25 ClientSocket(TCPSocketConnection *sock) : sock(sock), preread(-1), timeout(1.5) {
yamaguch 0:cbc8e17f7043 26 sock->set_blocking(false, (int) (timeout * 1000));
yamaguch 0:cbc8e17f7043 27 }
yamaguch 0:cbc8e17f7043 28
yamaguch 0:cbc8e17f7043 29 ~ClientSocket() {
yamaguch 0:cbc8e17f7043 30 // do NOT close in the destructor.
yamaguch 0:cbc8e17f7043 31 }
yamaguch 0:cbc8e17f7043 32
yamaguch 0:cbc8e17f7043 33 void setTimeout(float timeout) {
yamaguch 0:cbc8e17f7043 34 sock->set_blocking(false, (int) (timeout * 1000));
yamaguch 0:cbc8e17f7043 35 this->timeout = timeout;
yamaguch 0:cbc8e17f7043 36 }
yamaguch 0:cbc8e17f7043 37
yamaguch 0:cbc8e17f7043 38 bool available() {
yamaguch 0:cbc8e17f7043 39 if (preread == -1) {
yamaguch 0:cbc8e17f7043 40 char c;
yamaguch 0:cbc8e17f7043 41 sock->set_blocking(false, 0);
yamaguch 0:cbc8e17f7043 42 if (sock->receive((char *) &c, 1) <= 0) {
yamaguch 0:cbc8e17f7043 43 sock->set_blocking(false, (int) (timeout * 1000));
yamaguch 0:cbc8e17f7043 44 return false;
yamaguch 0:cbc8e17f7043 45 }
yamaguch 0:cbc8e17f7043 46 preread = c & 255;
yamaguch 0:cbc8e17f7043 47 sock->set_blocking(false, (int) (timeout * 1000));
yamaguch 0:cbc8e17f7043 48 }
yamaguch 0:cbc8e17f7043 49
yamaguch 0:cbc8e17f7043 50 return true;
yamaguch 0:cbc8e17f7043 51 }
yamaguch 0:cbc8e17f7043 52
yamaguch 0:cbc8e17f7043 53 int read() {
yamaguch 0:cbc8e17f7043 54 char c;
yamaguch 0:cbc8e17f7043 55 if (preread != -1) {
yamaguch 0:cbc8e17f7043 56 c = (char) preread;
yamaguch 0:cbc8e17f7043 57 preread = -1;
yamaguch 0:cbc8e17f7043 58 } else {
yamaguch 0:cbc8e17f7043 59 if (sock->receive((char *) &c, 1) <= 0)
yamaguch 0:cbc8e17f7043 60 return -1;
yamaguch 0:cbc8e17f7043 61 }
yamaguch 0:cbc8e17f7043 62
yamaguch 0:cbc8e17f7043 63 return c & 255;
yamaguch 0:cbc8e17f7043 64 }
yamaguch 0:cbc8e17f7043 65
yamaguch 0:cbc8e17f7043 66 int read(char *buf, int size) {
yamaguch 0:cbc8e17f7043 67 if (size <= 0)
yamaguch 0:cbc8e17f7043 68 return 0;
yamaguch 0:cbc8e17f7043 69
yamaguch 0:cbc8e17f7043 70 int nread = 0;
yamaguch 0:cbc8e17f7043 71 if (preread != -1) {
yamaguch 0:cbc8e17f7043 72 nread = 1;
yamaguch 0:cbc8e17f7043 73 *buf++ = (char) preread;
yamaguch 0:cbc8e17f7043 74 preread = -1;
yamaguch 0:cbc8e17f7043 75 size--;
yamaguch 0:cbc8e17f7043 76 }
yamaguch 0:cbc8e17f7043 77
yamaguch 0:cbc8e17f7043 78 if (size > 0) {
yamaguch 0:cbc8e17f7043 79 size = sock->receive_all(buf, size - 1);
yamaguch 0:cbc8e17f7043 80 if (size > 0)
yamaguch 0:cbc8e17f7043 81 nread += size;
yamaguch 0:cbc8e17f7043 82 }
yamaguch 0:cbc8e17f7043 83
yamaguch 0:cbc8e17f7043 84 return (nread > 0) ? nread : -1;
yamaguch 0:cbc8e17f7043 85 }
yamaguch 0:cbc8e17f7043 86
yamaguch 0:cbc8e17f7043 87 int scanf(const char *format, ...) {
yamaguch 0:cbc8e17f7043 88 va_list argp;
yamaguch 0:cbc8e17f7043 89 va_start(argp, format);
yamaguch 0:cbc8e17f7043 90 char buf[256];
yamaguch 0:cbc8e17f7043 91
yamaguch 0:cbc8e17f7043 92 int len = read(buf, sizeof(buf) - 1);
yamaguch 0:cbc8e17f7043 93 if (len <= 0)
yamaguch 0:cbc8e17f7043 94 return 0;
yamaguch 0:cbc8e17f7043 95 buf[len] = '\0';
yamaguch 0:cbc8e17f7043 96
yamaguch 0:cbc8e17f7043 97 int ret = vsscanf(buf, format, argp);
yamaguch 0:cbc8e17f7043 98 va_end(argp);
yamaguch 0:cbc8e17f7043 99
yamaguch 0:cbc8e17f7043 100 return ret;
yamaguch 0:cbc8e17f7043 101 }
yamaguch 0:cbc8e17f7043 102
yamaguch 0:cbc8e17f7043 103 int write(char c) {
yamaguch 0:cbc8e17f7043 104 return sock->send_all(&c, 1);
yamaguch 0:cbc8e17f7043 105 }
yamaguch 0:cbc8e17f7043 106
yamaguch 0:cbc8e17f7043 107 int write(char *buf, int size) {
yamaguch 0:cbc8e17f7043 108 return sock->send_all(buf, size);
yamaguch 0:cbc8e17f7043 109 }
yamaguch 0:cbc8e17f7043 110
yamaguch 0:cbc8e17f7043 111 int printf(const char *format, ...) {
yamaguch 0:cbc8e17f7043 112 va_list argp;
yamaguch 0:cbc8e17f7043 113 va_start(argp, format);
yamaguch 0:cbc8e17f7043 114 char buf[256];
yamaguch 0:cbc8e17f7043 115
yamaguch 0:cbc8e17f7043 116 int len = vsnprintf(buf, sizeof(buf), format, argp);
yamaguch 0:cbc8e17f7043 117 va_end(argp);
yamaguch 0:cbc8e17f7043 118
yamaguch 0:cbc8e17f7043 119 return write(buf, len);
yamaguch 0:cbc8e17f7043 120 }
yamaguch 0:cbc8e17f7043 121
yamaguch 0:cbc8e17f7043 122 void close() {
yamaguch 0:cbc8e17f7043 123 if (sock) {
yamaguch 0:cbc8e17f7043 124 sock->close();
yamaguch 0:cbc8e17f7043 125 delete sock;
yamaguch 0:cbc8e17f7043 126 sock = 0;
yamaguch 0:cbc8e17f7043 127 }
yamaguch 0:cbc8e17f7043 128 }
yamaguch 0:cbc8e17f7043 129
yamaguch 0:cbc8e17f7043 130 bool connected() {
yamaguch 0:cbc8e17f7043 131 return sock && sock->is_connected();
yamaguch 0:cbc8e17f7043 132 }
yamaguch 0:cbc8e17f7043 133
yamaguch 0:cbc8e17f7043 134 operator bool() {
yamaguch 0:cbc8e17f7043 135 return connected();
yamaguch 0:cbc8e17f7043 136 }
yamaguch 0:cbc8e17f7043 137
yamaguch 0:cbc8e17f7043 138 private:
yamaguch 0:cbc8e17f7043 139 TCPSocketConnection *sock;
yamaguch 0:cbc8e17f7043 140 int preread;
yamaguch 0:cbc8e17f7043 141 float timeout;
yamaguch 0:cbc8e17f7043 142 };
yamaguch 0:cbc8e17f7043 143
yamaguch 0:cbc8e17f7043 144 /**
yamaguch 0:cbc8e17f7043 145 * server socket class for handling incoming communication requests
yamaguch 0:cbc8e17f7043 146 */
yamaguch 0:cbc8e17f7043 147 class ServerSocket {
yamaguch 0:cbc8e17f7043 148 public:
yamaguch 0:cbc8e17f7043 149 ServerSocket(int port) {
yamaguch 0:cbc8e17f7043 150 if (EthernetInterface::getIPAddress() == NULL) {
yamaguch 0:cbc8e17f7043 151 EthernetInterface::init();
yamaguch 0:cbc8e17f7043 152 EthernetInterface::connect();
yamaguch 0:cbc8e17f7043 153 }
yamaguch 0:cbc8e17f7043 154 ssock.bind(port);
yamaguch 0:cbc8e17f7043 155 ssock.listen();
yamaguch 0:cbc8e17f7043 156 }
yamaguch 0:cbc8e17f7043 157
yamaguch 0:cbc8e17f7043 158 ClientSocket accept() {
yamaguch 0:cbc8e17f7043 159 TCPSocketConnection *sock = new TCPSocketConnection();
yamaguch 0:cbc8e17f7043 160 ssock.accept(*sock);
yamaguch 0:cbc8e17f7043 161
yamaguch 0:cbc8e17f7043 162 return ClientSocket(sock);
yamaguch 0:cbc8e17f7043 163 }
yamaguch 0:cbc8e17f7043 164
yamaguch 0:cbc8e17f7043 165 private:
yamaguch 0:cbc8e17f7043 166 TCPSocketServer ssock;
yamaguch 0:cbc8e17f7043 167 };
yamaguch 0:cbc8e17f7043 168
yamaguch 0:cbc8e17f7043 169 /**
yamaguch 0:cbc8e17f7043 170 * class for handling datagram
yamaguch 0:cbc8e17f7043 171 */
yamaguch 0:cbc8e17f7043 172 class DatagramSocket {
yamaguch 0:cbc8e17f7043 173 public:
yamaguch 0:cbc8e17f7043 174 DatagramSocket(int port = 0, int bufsize = 512) : bufsize(bufsize) {
yamaguch 0:cbc8e17f7043 175 if (EthernetInterface::getIPAddress() == NULL) {
yamaguch 0:cbc8e17f7043 176 EthernetInterface::init();
yamaguch 0:cbc8e17f7043 177 EthernetInterface::connect();
yamaguch 0:cbc8e17f7043 178 }
yamaguch 0:cbc8e17f7043 179 buf = new char[bufsize + 1];
yamaguch 0:cbc8e17f7043 180 usock.init();
yamaguch 0:cbc8e17f7043 181 usock.bind(port);
yamaguch 0:cbc8e17f7043 182 usock.set_blocking(false, 1500);
yamaguch 0:cbc8e17f7043 183 }
yamaguch 0:cbc8e17f7043 184
yamaguch 0:cbc8e17f7043 185 DatagramSocket(Endpoint& local, int bufsize = 512) : bufsize(bufsize) {
yamaguch 0:cbc8e17f7043 186 if (EthernetInterface::getIPAddress() == NULL) {
yamaguch 0:cbc8e17f7043 187 EthernetInterface::init();
yamaguch 0:cbc8e17f7043 188 EthernetInterface::connect();
yamaguch 0:cbc8e17f7043 189 }
yamaguch 0:cbc8e17f7043 190 buf = new char[bufsize + 1];
yamaguch 0:cbc8e17f7043 191 usock.init();
yamaguch 0:cbc8e17f7043 192 usock.bind(local.get_port());
yamaguch 0:cbc8e17f7043 193 usock.set_blocking(false, 1500);
yamaguch 0:cbc8e17f7043 194 }
yamaguch 0:cbc8e17f7043 195
yamaguch 0:cbc8e17f7043 196 ~DatagramSocket() {
yamaguch 0:cbc8e17f7043 197 delete[] buf;
yamaguch 0:cbc8e17f7043 198 }
yamaguch 0:cbc8e17f7043 199
yamaguch 0:cbc8e17f7043 200 void setTimeout(float timeout = 1.5) {
yamaguch 0:cbc8e17f7043 201 usock.set_blocking(false, (int) (timeout * 1000));
yamaguch 0:cbc8e17f7043 202 }
yamaguch 0:cbc8e17f7043 203
yamaguch 0:cbc8e17f7043 204 int write(char *buf, int length) {
yamaguch 0:cbc8e17f7043 205 if (length > bufsize) length = bufsize;
yamaguch 0:cbc8e17f7043 206 this->length = length;
yamaguch 0:cbc8e17f7043 207 memcpy(this->buf, buf, length);
yamaguch 0:cbc8e17f7043 208
yamaguch 0:cbc8e17f7043 209 return length;
yamaguch 0:cbc8e17f7043 210 }
yamaguch 0:cbc8e17f7043 211
yamaguch 0:cbc8e17f7043 212 int printf(const char* format, ...) {
yamaguch 0:cbc8e17f7043 213 va_list argp;
yamaguch 0:cbc8e17f7043 214 va_start(argp, format);
yamaguch 0:cbc8e17f7043 215 int len = vsnprintf(buf, bufsize, format, argp);
yamaguch 0:cbc8e17f7043 216 va_end(argp);
yamaguch 0:cbc8e17f7043 217 if (len > 0)
yamaguch 0:cbc8e17f7043 218 length = len;
yamaguch 0:cbc8e17f7043 219
yamaguch 0:cbc8e17f7043 220 return len;
yamaguch 0:cbc8e17f7043 221 }
yamaguch 0:cbc8e17f7043 222
yamaguch 0:cbc8e17f7043 223 void send(const char *host, int port) {
yamaguch 0:cbc8e17f7043 224 Endpoint remote;
yamaguch 0:cbc8e17f7043 225 remote.reset_address();
yamaguch 0:cbc8e17f7043 226 remote.set_address(host, port);
yamaguch 0:cbc8e17f7043 227 usock.sendTo(remote, buf, length);
yamaguch 0:cbc8e17f7043 228 }
yamaguch 0:cbc8e17f7043 229
yamaguch 0:cbc8e17f7043 230 void send(Endpoint& remote) {
yamaguch 0:cbc8e17f7043 231 usock.sendTo(remote, buf, length);
yamaguch 0:cbc8e17f7043 232 }
yamaguch 0:cbc8e17f7043 233
yamaguch 0:cbc8e17f7043 234 int receive(char *host = 0, int *port = 0) {
yamaguch 0:cbc8e17f7043 235 Endpoint remote;
yamaguch 0:cbc8e17f7043 236 length = usock.receiveFrom(remote, buf, bufsize);
yamaguch 0:cbc8e17f7043 237 if (length > 0) {
yamaguch 0:cbc8e17f7043 238 if (host) strcpy(host, remote.get_address());
yamaguch 0:cbc8e17f7043 239 if (port) *port = remote.get_port();
yamaguch 0:cbc8e17f7043 240 }
yamaguch 0:cbc8e17f7043 241
yamaguch 0:cbc8e17f7043 242 return length;
yamaguch 0:cbc8e17f7043 243 }
yamaguch 0:cbc8e17f7043 244
yamaguch 0:cbc8e17f7043 245 int receive(Endpoint& remote) {
yamaguch 0:cbc8e17f7043 246 return usock.receiveFrom(remote, buf, bufsize);
yamaguch 0:cbc8e17f7043 247 }
yamaguch 0:cbc8e17f7043 248
yamaguch 0:cbc8e17f7043 249 int read(char *buf, int size) {
yamaguch 0:cbc8e17f7043 250 int len = length < size ? length : size;
yamaguch 0:cbc8e17f7043 251 if (len > 0)
yamaguch 0:cbc8e17f7043 252 memcpy(buf, this->buf, len);
yamaguch 0:cbc8e17f7043 253
yamaguch 0:cbc8e17f7043 254 return len;
yamaguch 0:cbc8e17f7043 255 }
yamaguch 0:cbc8e17f7043 256
yamaguch 0:cbc8e17f7043 257 int scanf(const char* format, ...) {
yamaguch 0:cbc8e17f7043 258 va_list argp;
yamaguch 0:cbc8e17f7043 259 va_start(argp, format);
yamaguch 0:cbc8e17f7043 260 buf[length] = '\0';
yamaguch 0:cbc8e17f7043 261 int ret = vsscanf(buf, format, argp);
yamaguch 0:cbc8e17f7043 262 va_end(argp);
yamaguch 0:cbc8e17f7043 263
yamaguch 0:cbc8e17f7043 264 return ret;
yamaguch 0:cbc8e17f7043 265 }
yamaguch 0:cbc8e17f7043 266
yamaguch 0:cbc8e17f7043 267 private:
yamaguch 0:cbc8e17f7043 268 char *buf;
yamaguch 0:cbc8e17f7043 269 int bufsize;
yamaguch 0:cbc8e17f7043 270 int length;
yamaguch 0:cbc8e17f7043 271 UDPSocket usock;
yamaguch 0:cbc8e17f7043 272 };
yamaguch 0:cbc8e17f7043 273
yamaguch 0:cbc8e17f7043 274 #endif