Websocket_Sample for MurataTypeYD

Dependencies:   mbed picojson

Committer:
komoritan
Date:
Thu Mar 12 12:15:46 2015 +0000
Revision:
1:b5ac0f971f43
Parent:
0:14bd24b5a77f
Fixed

Who changed what in which revision?

UserRevisionLine numberNew contents of line
komoritan 0:14bd24b5a77f 1 #include "Websocket.h"
komoritan 0:14bd24b5a77f 2
komoritan 0:14bd24b5a77f 3 #define MAX_TRY_WRITE 20
komoritan 0:14bd24b5a77f 4 #define MAX_TRY_READ 10
komoritan 0:14bd24b5a77f 5
komoritan 0:14bd24b5a77f 6 //Debug is disabled by default
komoritan 0:14bd24b5a77f 7 #if 1
komoritan 0:14bd24b5a77f 8 #define DBG(x, ...) std::printf("[WebSocket : DBG]"x"\r\n", ##__VA_ARGS__);
komoritan 0:14bd24b5a77f 9 #define WARN(x, ...) std::printf("[WebSocket : WARN]"x"\r\n", ##__VA_ARGS__);
komoritan 0:14bd24b5a77f 10 #define ERR(x, ...) std::printf("[WebSocket : ERR]"x"\r\n", ##__VA_ARGS__);
komoritan 0:14bd24b5a77f 11 #else
komoritan 0:14bd24b5a77f 12 #define DBG(x, ...)
komoritan 0:14bd24b5a77f 13 #define WARN(x, ...)
komoritan 0:14bd24b5a77f 14 #define ERR(x, ...)
komoritan 0:14bd24b5a77f 15 #endif
komoritan 0:14bd24b5a77f 16
komoritan 0:14bd24b5a77f 17 #define INFO(x, ...) printf("[WebSocket : INFO]"x"\r\n", ##__VA_ARGS__);
komoritan 0:14bd24b5a77f 18
komoritan 0:14bd24b5a77f 19 Websocket::Websocket(char * url) {
komoritan 0:14bd24b5a77f 20 fillFields(url);
komoritan 0:14bd24b5a77f 21 socket.set_blocking(false, 400);
komoritan 0:14bd24b5a77f 22 }
komoritan 0:14bd24b5a77f 23
komoritan 0:14bd24b5a77f 24 void Websocket::fillFields(char * url) {
komoritan 0:14bd24b5a77f 25 int ret = parseURL(url, scheme, sizeof(scheme), host, sizeof(host), &port, path, sizeof(path));
komoritan 0:14bd24b5a77f 26 if(ret)
komoritan 0:14bd24b5a77f 27 {
komoritan 0:14bd24b5a77f 28 ERR("URL parsing failed; please use: \"ws://ip-or-domain[:port]/path\"");
komoritan 0:14bd24b5a77f 29 return;
komoritan 0:14bd24b5a77f 30 }
komoritan 0:14bd24b5a77f 31
komoritan 0:14bd24b5a77f 32 if(port == 0) //TODO do handle WSS->443
komoritan 0:14bd24b5a77f 33 {
komoritan 0:14bd24b5a77f 34 port = 80;
komoritan 0:14bd24b5a77f 35 }
komoritan 0:14bd24b5a77f 36
komoritan 0:14bd24b5a77f 37 if(strcmp(scheme, "ws"))
komoritan 0:14bd24b5a77f 38 {
komoritan 0:14bd24b5a77f 39 ERR("Wrong scheme, please use \"ws\" instead");
komoritan 0:14bd24b5a77f 40 }
komoritan 0:14bd24b5a77f 41 }
komoritan 0:14bd24b5a77f 42
komoritan 0:14bd24b5a77f 43 int Websocket::parseURL(const char* url, char* scheme, size_t maxSchemeLen, char* host, size_t maxHostLen, uint16_t* port, char* path, size_t maxPathLen) //Parse URL
komoritan 0:14bd24b5a77f 44 {
komoritan 0:14bd24b5a77f 45 char* schemePtr = (char*) url;
komoritan 0:14bd24b5a77f 46 char* hostPtr = (char*) strstr(url, "://");
komoritan 0:14bd24b5a77f 47 if(hostPtr == NULL)
komoritan 0:14bd24b5a77f 48 {
komoritan 0:14bd24b5a77f 49 WARN("Could not find host");
komoritan 0:14bd24b5a77f 50 return -1; //URL is invalid
komoritan 0:14bd24b5a77f 51 }
komoritan 0:14bd24b5a77f 52
komoritan 0:14bd24b5a77f 53 if( maxSchemeLen < hostPtr - schemePtr + 1 ) //including NULL-terminating char
komoritan 0:14bd24b5a77f 54 {
komoritan 0:14bd24b5a77f 55 WARN("Scheme str is too small (%d >= %d)", maxSchemeLen, hostPtr - schemePtr + 1);
komoritan 0:14bd24b5a77f 56 return -1;
komoritan 0:14bd24b5a77f 57 }
komoritan 0:14bd24b5a77f 58 memcpy(scheme, schemePtr, hostPtr - schemePtr);
komoritan 0:14bd24b5a77f 59 scheme[hostPtr - schemePtr] = '\0';
komoritan 0:14bd24b5a77f 60
komoritan 0:14bd24b5a77f 61 hostPtr+=3;
komoritan 0:14bd24b5a77f 62
komoritan 0:14bd24b5a77f 63 size_t hostLen = 0;
komoritan 0:14bd24b5a77f 64
komoritan 0:14bd24b5a77f 65 char* portPtr = strchr(hostPtr, ':');
komoritan 0:14bd24b5a77f 66 if( portPtr != NULL )
komoritan 0:14bd24b5a77f 67 {
komoritan 0:14bd24b5a77f 68 hostLen = portPtr - hostPtr;
komoritan 0:14bd24b5a77f 69 portPtr++;
komoritan 0:14bd24b5a77f 70 if( sscanf(portPtr, "%hu", port) != 1)
komoritan 0:14bd24b5a77f 71 {
komoritan 0:14bd24b5a77f 72 WARN("Could not find port");
komoritan 0:14bd24b5a77f 73 return -1;
komoritan 0:14bd24b5a77f 74 }
komoritan 0:14bd24b5a77f 75 }
komoritan 0:14bd24b5a77f 76 else
komoritan 0:14bd24b5a77f 77 {
komoritan 0:14bd24b5a77f 78 *port=0;
komoritan 0:14bd24b5a77f 79 }
komoritan 0:14bd24b5a77f 80 char* pathPtr = strchr(hostPtr, '/');
komoritan 0:14bd24b5a77f 81 if( hostLen == 0 )
komoritan 0:14bd24b5a77f 82 {
komoritan 0:14bd24b5a77f 83 hostLen = pathPtr - hostPtr;
komoritan 0:14bd24b5a77f 84 }
komoritan 0:14bd24b5a77f 85
komoritan 0:14bd24b5a77f 86 if( maxHostLen < hostLen + 1 ) //including NULL-terminating char
komoritan 0:14bd24b5a77f 87 {
komoritan 0:14bd24b5a77f 88 WARN("Host str is too small (%d >= %d)", maxHostLen, hostLen + 1);
komoritan 0:14bd24b5a77f 89 return -1;
komoritan 0:14bd24b5a77f 90 }
komoritan 0:14bd24b5a77f 91 memcpy(host, hostPtr, hostLen);
komoritan 0:14bd24b5a77f 92 host[hostLen] = '\0';
komoritan 0:14bd24b5a77f 93
komoritan 0:14bd24b5a77f 94 size_t pathLen;
komoritan 0:14bd24b5a77f 95 char* fragmentPtr = strchr(hostPtr, '#');
komoritan 0:14bd24b5a77f 96 if(fragmentPtr != NULL)
komoritan 0:14bd24b5a77f 97 {
komoritan 0:14bd24b5a77f 98 pathLen = fragmentPtr - pathPtr;
komoritan 0:14bd24b5a77f 99 }
komoritan 0:14bd24b5a77f 100 else
komoritan 0:14bd24b5a77f 101 {
komoritan 0:14bd24b5a77f 102 pathLen = strlen(pathPtr);
komoritan 0:14bd24b5a77f 103 }
komoritan 0:14bd24b5a77f 104
komoritan 0:14bd24b5a77f 105 if( maxPathLen < pathLen + 1 ) //including NULL-terminating char
komoritan 0:14bd24b5a77f 106 {
komoritan 0:14bd24b5a77f 107 WARN("Path str is too small (%d >= %d)", maxPathLen, pathLen + 1);
komoritan 0:14bd24b5a77f 108 return -1;
komoritan 0:14bd24b5a77f 109 }
komoritan 0:14bd24b5a77f 110 memcpy(path, pathPtr, pathLen);
komoritan 0:14bd24b5a77f 111 path[pathLen] = '\0';
komoritan 0:14bd24b5a77f 112
komoritan 0:14bd24b5a77f 113 return 0;
komoritan 0:14bd24b5a77f 114 }
komoritan 0:14bd24b5a77f 115
komoritan 0:14bd24b5a77f 116
komoritan 0:14bd24b5a77f 117 bool Websocket::connect() {
komoritan 0:14bd24b5a77f 118 char cmd[200];
komoritan 0:14bd24b5a77f 119
komoritan 0:14bd24b5a77f 120 while (socket.connect(host, port) < 0) {
komoritan 0:14bd24b5a77f 121 ERR("Unable to connect to (%s) on port (%d)", host, port);
komoritan 0:14bd24b5a77f 122 wait(0.2);
komoritan 0:14bd24b5a77f 123 return false;
komoritan 0:14bd24b5a77f 124 }
komoritan 0:14bd24b5a77f 125
komoritan 0:14bd24b5a77f 126 // sent http header to upgrade to the ws protocol
komoritan 0:14bd24b5a77f 127 sprintf(cmd, "GET %s HTTP/1.1\r\n", path);
komoritan 0:14bd24b5a77f 128 write(cmd, strlen(cmd));
komoritan 0:14bd24b5a77f 129
komoritan 0:14bd24b5a77f 130 sprintf(cmd, "Host: %s:%d\r\n", host, port);
komoritan 0:14bd24b5a77f 131 write(cmd, strlen(cmd));
komoritan 0:14bd24b5a77f 132
komoritan 0:14bd24b5a77f 133 sprintf(cmd, "Upgrade: WebSocket\r\n");
komoritan 0:14bd24b5a77f 134 write(cmd, strlen(cmd));
komoritan 0:14bd24b5a77f 135
komoritan 0:14bd24b5a77f 136 sprintf(cmd, "Connection: Upgrade\r\n");
komoritan 0:14bd24b5a77f 137 write(cmd, strlen(cmd));
komoritan 0:14bd24b5a77f 138
komoritan 0:14bd24b5a77f 139 sprintf(cmd, "Sec-WebSocket-Key: L159VM0TWUzyDxwJEIEzjw==\r\n");
komoritan 0:14bd24b5a77f 140 write(cmd, strlen(cmd));
komoritan 0:14bd24b5a77f 141
komoritan 0:14bd24b5a77f 142 sprintf(cmd, "Sec-WebSocket-Version: 13\r\n\r\n");
komoritan 0:14bd24b5a77f 143 int ret = write(cmd, strlen(cmd));
komoritan 0:14bd24b5a77f 144 if (ret != strlen(cmd)) {
komoritan 0:14bd24b5a77f 145 close();
komoritan 0:14bd24b5a77f 146 ERR("Could not send request");
komoritan 0:14bd24b5a77f 147 return false;
komoritan 0:14bd24b5a77f 148 }
komoritan 0:14bd24b5a77f 149 // KTEA ADD S
komoritan 0:14bd24b5a77f 150 // シェイクハンズのコマンドを送ってからレスポンスが返ってくるまで少し待つ必要があるためwaitを追加
komoritan 0:14bd24b5a77f 151 wait(3.0);
komoritan 0:14bd24b5a77f 152 // KTEA ADD E
komoritan 0:14bd24b5a77f 153
komoritan 0:14bd24b5a77f 154 ret = read(cmd, 200, 100);
komoritan 0:14bd24b5a77f 155 if (ret < 0) {
komoritan 0:14bd24b5a77f 156 close();
komoritan 0:14bd24b5a77f 157 ERR("Could not receive answer\r\n");
komoritan 0:14bd24b5a77f 158 return false;
komoritan 0:14bd24b5a77f 159 }
komoritan 0:14bd24b5a77f 160
komoritan 0:14bd24b5a77f 161 cmd[ret] = '\0';
komoritan 0:14bd24b5a77f 162 DBG("recv: %s\r\n", cmd);
komoritan 0:14bd24b5a77f 163
komoritan 0:14bd24b5a77f 164 if ( strstr(cmd, "DdLWT/1JcX+nQFHebYP+rqEx5xI=") == NULL ) {
komoritan 0:14bd24b5a77f 165 ERR("Wrong answer from server, got \"%s\" instead\r\n", cmd);
komoritan 0:14bd24b5a77f 166 do {
komoritan 0:14bd24b5a77f 167 ret = read(cmd, 200, 100);
komoritan 0:14bd24b5a77f 168 if (ret < 0) {
komoritan 0:14bd24b5a77f 169 ERR("Could not receive answer\r\n");
komoritan 0:14bd24b5a77f 170 return false;
komoritan 0:14bd24b5a77f 171 }
komoritan 0:14bd24b5a77f 172 cmd[ret] = '\0';
komoritan 0:14bd24b5a77f 173 printf("%s",cmd);
komoritan 0:14bd24b5a77f 174 } while (ret > 0);
komoritan 0:14bd24b5a77f 175 close();
komoritan 0:14bd24b5a77f 176 return false;
komoritan 0:14bd24b5a77f 177 }
komoritan 0:14bd24b5a77f 178
komoritan 0:14bd24b5a77f 179 INFO("\r\nhost: %s\r\npath: %s\r\nport: %d\r\n\r\n", host, path, port);
komoritan 0:14bd24b5a77f 180 return true;
komoritan 0:14bd24b5a77f 181 }
komoritan 0:14bd24b5a77f 182
komoritan 0:14bd24b5a77f 183 int Websocket::sendLength(uint32_t len, char * msg) {
komoritan 0:14bd24b5a77f 184
komoritan 0:14bd24b5a77f 185 if (len < 126) {
komoritan 0:14bd24b5a77f 186 msg[0] = len | (1<<7);
komoritan 0:14bd24b5a77f 187 return 1;
komoritan 0:14bd24b5a77f 188 } else if (len < 65535) {
komoritan 0:14bd24b5a77f 189 msg[0] = 126 | (1<<7);
komoritan 0:14bd24b5a77f 190 msg[1] = (len >> 8) & 0xff;
komoritan 0:14bd24b5a77f 191 msg[2] = len & 0xff;
komoritan 0:14bd24b5a77f 192 return 3;
komoritan 0:14bd24b5a77f 193 } else {
komoritan 0:14bd24b5a77f 194 msg[0] = 127 | (1<<7);
komoritan 0:14bd24b5a77f 195 for (int i = 0; i < 8; i++) {
komoritan 0:14bd24b5a77f 196 msg[i+1] = (len >> i*8) & 0xff;
komoritan 0:14bd24b5a77f 197 }
komoritan 0:14bd24b5a77f 198 return 9;
komoritan 0:14bd24b5a77f 199 }
komoritan 0:14bd24b5a77f 200 }
komoritan 0:14bd24b5a77f 201
komoritan 0:14bd24b5a77f 202 int Websocket::readChar(char * pC, bool block) {
komoritan 0:14bd24b5a77f 203 return read(pC, 1, 1);
komoritan 0:14bd24b5a77f 204 }
komoritan 0:14bd24b5a77f 205
komoritan 0:14bd24b5a77f 206 int Websocket::sendOpcode(uint8_t opcode, char * msg) {
komoritan 0:14bd24b5a77f 207 msg[0] = 0x80 | (opcode & 0x0f);
komoritan 0:14bd24b5a77f 208 return 1;
komoritan 0:14bd24b5a77f 209 }
komoritan 0:14bd24b5a77f 210
komoritan 0:14bd24b5a77f 211 int Websocket::sendMask(char * msg) {
komoritan 0:14bd24b5a77f 212 for (int i = 0; i < 4; i++) {
komoritan 0:14bd24b5a77f 213 msg[i] = 0;
komoritan 0:14bd24b5a77f 214 }
komoritan 0:14bd24b5a77f 215 return 4;
komoritan 0:14bd24b5a77f 216 }
komoritan 0:14bd24b5a77f 217
komoritan 0:14bd24b5a77f 218 int Websocket::send(char * str) {
komoritan 0:14bd24b5a77f 219 char msg[strlen(str) + 15];
komoritan 0:14bd24b5a77f 220 int idx = 0;
komoritan 0:14bd24b5a77f 221 idx = sendOpcode(0x01, msg);
komoritan 0:14bd24b5a77f 222 idx += sendLength(strlen(str), msg + idx);
komoritan 0:14bd24b5a77f 223 idx += sendMask(msg + idx);
komoritan 0:14bd24b5a77f 224 memcpy(msg+idx, str, strlen(str));
komoritan 0:14bd24b5a77f 225 int res = write(msg, idx + strlen(str));
komoritan 0:14bd24b5a77f 226 return res;
komoritan 0:14bd24b5a77f 227 }
komoritan 0:14bd24b5a77f 228
komoritan 0:14bd24b5a77f 229
komoritan 0:14bd24b5a77f 230 bool Websocket::read(char * message) {
komoritan 0:14bd24b5a77f 231 int i = 0;
komoritan 0:14bd24b5a77f 232 uint32_t len_msg;
komoritan 0:14bd24b5a77f 233 char opcode = 0;
komoritan 0:14bd24b5a77f 234 char c;
komoritan 0:14bd24b5a77f 235 char mask[4] = {0, 0, 0, 0};
komoritan 0:14bd24b5a77f 236 bool is_masked = false;
komoritan 0:14bd24b5a77f 237 Timer tmr;
komoritan 0:14bd24b5a77f 238
komoritan 0:14bd24b5a77f 239 // read the opcode
komoritan 0:14bd24b5a77f 240 tmr.start();
komoritan 0:14bd24b5a77f 241 while (true) {
komoritan 0:14bd24b5a77f 242 if (tmr.read() > 3) {
komoritan 0:14bd24b5a77f 243 DBG("timeout ws\r\n");
komoritan 0:14bd24b5a77f 244 return false;
komoritan 0:14bd24b5a77f 245 }
komoritan 0:14bd24b5a77f 246
komoritan 0:14bd24b5a77f 247 if(!socket.is_connected())
komoritan 0:14bd24b5a77f 248 {
komoritan 0:14bd24b5a77f 249 WARN("Connection was closed by server");
komoritan 0:14bd24b5a77f 250 return false;
komoritan 0:14bd24b5a77f 251 }
komoritan 0:14bd24b5a77f 252
komoritan 0:14bd24b5a77f 253 socket.set_blocking(false, 1);
komoritan 0:14bd24b5a77f 254 if (socket.receive(&opcode, 1) != 1) {
komoritan 0:14bd24b5a77f 255 socket.set_blocking(false, 2000);
komoritan 0:14bd24b5a77f 256 return false;
komoritan 0:14bd24b5a77f 257 }
komoritan 0:14bd24b5a77f 258
komoritan 0:14bd24b5a77f 259 socket.set_blocking(false, 2000);
komoritan 0:14bd24b5a77f 260
komoritan 0:14bd24b5a77f 261 if (opcode == 0x81)
komoritan 0:14bd24b5a77f 262 break;
komoritan 0:14bd24b5a77f 263 }
komoritan 0:14bd24b5a77f 264 DBG("opcode: 0x%X\r\n", opcode);
komoritan 0:14bd24b5a77f 265
komoritan 0:14bd24b5a77f 266 readChar(&c);
komoritan 0:14bd24b5a77f 267 len_msg = c & 0x7f;
komoritan 0:14bd24b5a77f 268 is_masked = c & 0x80;
komoritan 0:14bd24b5a77f 269 if (len_msg == 126) {
komoritan 0:14bd24b5a77f 270 readChar(&c);
komoritan 0:14bd24b5a77f 271 len_msg = c << 8;
komoritan 0:14bd24b5a77f 272 readChar(&c);
komoritan 0:14bd24b5a77f 273 len_msg += c;
komoritan 0:14bd24b5a77f 274 } else if (len_msg == 127) {
komoritan 0:14bd24b5a77f 275 len_msg = 0;
komoritan 0:14bd24b5a77f 276 for (int i = 0; i < 8; i++) {
komoritan 0:14bd24b5a77f 277 readChar(&c);
komoritan 0:14bd24b5a77f 278 len_msg += (c << (7-i)*8);
komoritan 0:14bd24b5a77f 279 }
komoritan 0:14bd24b5a77f 280 }
komoritan 0:14bd24b5a77f 281
komoritan 0:14bd24b5a77f 282 if (len_msg == 0) {
komoritan 0:14bd24b5a77f 283 return false;
komoritan 0:14bd24b5a77f 284 }
komoritan 0:14bd24b5a77f 285 DBG("length: %d\r\n", len_msg);
komoritan 0:14bd24b5a77f 286
komoritan 0:14bd24b5a77f 287 if (is_masked) {
komoritan 0:14bd24b5a77f 288 for (i = 0; i < 4; i++)
komoritan 0:14bd24b5a77f 289 readChar(&c);
komoritan 0:14bd24b5a77f 290 mask[i] = c;
komoritan 0:14bd24b5a77f 291 }
komoritan 0:14bd24b5a77f 292
komoritan 0:14bd24b5a77f 293 int nb = read(message, len_msg, len_msg);
komoritan 0:14bd24b5a77f 294 if (nb != len_msg)
komoritan 0:14bd24b5a77f 295 return false;
komoritan 0:14bd24b5a77f 296
komoritan 0:14bd24b5a77f 297 for (i = 0; i < len_msg; i++) {
komoritan 0:14bd24b5a77f 298 message[i] = message[i] ^ mask[i % 4];
komoritan 0:14bd24b5a77f 299 }
komoritan 0:14bd24b5a77f 300
komoritan 0:14bd24b5a77f 301 message[len_msg] = '\0';
komoritan 0:14bd24b5a77f 302
komoritan 0:14bd24b5a77f 303 return true;
komoritan 0:14bd24b5a77f 304 }
komoritan 0:14bd24b5a77f 305
komoritan 0:14bd24b5a77f 306 bool Websocket::close() {
komoritan 0:14bd24b5a77f 307 if (!is_connected())
komoritan 0:14bd24b5a77f 308 return false;
komoritan 0:14bd24b5a77f 309
komoritan 0:14bd24b5a77f 310 int ret = socket.close();
komoritan 0:14bd24b5a77f 311 if (ret < 0) {
komoritan 0:14bd24b5a77f 312 ERR("Could not disconnect");
komoritan 0:14bd24b5a77f 313 return false;
komoritan 0:14bd24b5a77f 314 }
komoritan 0:14bd24b5a77f 315 return true;
komoritan 0:14bd24b5a77f 316 }
komoritan 0:14bd24b5a77f 317
komoritan 0:14bd24b5a77f 318 bool Websocket::is_connected() {
komoritan 0:14bd24b5a77f 319 return socket.is_connected();
komoritan 0:14bd24b5a77f 320 }
komoritan 0:14bd24b5a77f 321
komoritan 0:14bd24b5a77f 322 char* Websocket::getPath() {
komoritan 0:14bd24b5a77f 323 return path;
komoritan 0:14bd24b5a77f 324 }
komoritan 0:14bd24b5a77f 325
komoritan 0:14bd24b5a77f 326 int Websocket::write(char * str, int len) {
komoritan 0:14bd24b5a77f 327 int res = 0, idx = 0;
komoritan 0:14bd24b5a77f 328
komoritan 0:14bd24b5a77f 329 for (int j = 0; j < MAX_TRY_WRITE; j++) {
komoritan 0:14bd24b5a77f 330
komoritan 0:14bd24b5a77f 331 if(!socket.is_connected())
komoritan 0:14bd24b5a77f 332 {
komoritan 0:14bd24b5a77f 333 WARN("Connection was closed by server");
komoritan 0:14bd24b5a77f 334 break;
komoritan 0:14bd24b5a77f 335 }
komoritan 0:14bd24b5a77f 336
komoritan 0:14bd24b5a77f 337 if ((res = socket.send_all(str + idx, len - idx)) == -1)
komoritan 0:14bd24b5a77f 338 continue;
komoritan 0:14bd24b5a77f 339
komoritan 0:14bd24b5a77f 340 idx += res;
komoritan 0:14bd24b5a77f 341
komoritan 0:14bd24b5a77f 342 if (idx == len)
komoritan 0:14bd24b5a77f 343 return len;
komoritan 0:14bd24b5a77f 344 }
komoritan 0:14bd24b5a77f 345
komoritan 0:14bd24b5a77f 346 return (idx == 0) ? -1 : idx;
komoritan 0:14bd24b5a77f 347 }
komoritan 0:14bd24b5a77f 348
komoritan 0:14bd24b5a77f 349 int Websocket::read(char * str, int len, int min_len) {
komoritan 0:14bd24b5a77f 350 int res = 0, idx = 0;
komoritan 0:14bd24b5a77f 351
komoritan 0:14bd24b5a77f 352 for (int j = 0; j < MAX_TRY_WRITE; j++) {
komoritan 0:14bd24b5a77f 353
komoritan 0:14bd24b5a77f 354 if ((res = socket.receive_all(str + idx, len - idx)) == -1)
komoritan 0:14bd24b5a77f 355 continue;
komoritan 0:14bd24b5a77f 356
komoritan 0:14bd24b5a77f 357 idx += res;
komoritan 0:14bd24b5a77f 358
komoritan 0:14bd24b5a77f 359 if (idx == len || (min_len != -1 && idx > min_len))
komoritan 0:14bd24b5a77f 360 return idx;
komoritan 0:14bd24b5a77f 361 }
komoritan 0:14bd24b5a77f 362
komoritan 0:14bd24b5a77f 363 return (idx == 0) ? -1 : idx;
komoritan 0:14bd24b5a77f 364 }