Tell me, did you meet the description of the websockets protocol in Russian? I need to implement this protocol with the least amount of time.

Are there any tests to check? For example, an html page could send different requests and require specific responses.

  • As far as I know, the specs translated into Russian or its pieces do not exist on the websockets. Several test clients googling, I didn’t come across any recognized test suite - Duck Learns to Take Cover
  • "Websocket is one type of comet" @MAXOPKA, you are greatly mistaken. Comet is a crutch using various hacks: polling (ajax ordinary), long polling (hidden iframe), etc. Ie All that was used before the advent of Websocket and is used for the sake of compatibility with browsers. Read wiki - romeo

1 answer 1

Implemented.

Auxiliary classes:

class VString{ public: unsigned char *data; unsigned int sz; }; // Используется как указатель на данные class MString : public VString{ }; // Используется для выделения памяти 

Encoding / decoding functions.

 void DecodeData(VString read){ // need more data if(read.sz <= 4) return ; int fin = *read.data, opcode = fin&15, lpos; uint64 len = *(read.data+1); unsigned int mask = len & 128; if(opcode == LWSOC_CLOSE){ wel.closed(); return ; } switch(len&127){ case 126: len = *(unsigned short*)(read.data+2); lpos = 4; break; case 127: if(read.sz<10) return ; len = *(uint64*)(read.data+2); lpos = 10; break; default: lpos = 2; len &= 127; break; } // need more data if(read.sz < lpos || read.sz < lpos + len + (mask ? 4 : 0)) return ; if(mask){ mask = *(unsigned int*)(read.data+lpos); lpos += 4; } if(len > S1M){ wel.closed(); return ; } if(mask){ unsigned char *l = read.data + lpos; unsigned char *t = read.data + lpos + len; unsigned char *ft = t - (lpos + len) % 4; unsigned char *m = (unsigned char*)&mask; for(l; l < ft; l += 4) *(unsigned int*)l ^= mask; for(l; l < t; l++) *l ^= *m++; } AnalysData(wel, opcode, read.str(lpos, len)); return ; } EncodeData(int type, VString data, int fin = 1){ unsigned char buf[10]; int mask = rand(), lpos; if(!data) mask = 0; buf[0] = (fin << 7) + (type&15); if(data.sz <= 125){ buf[1] = 128 + data.sz; lpos = 2; }else if(data.sz <= 65535){ buf[1] = 128 + 126; *(unsigned short*)(buf + 2) = data.sz; lpos = 4; } else{ buf[1] = 128 + 127; *(uint64*)(buf + 2) = data.sz; lpos = 10; } MString ret; ret.Reserv(lpos + (mask ? 4 : 0) + data.sz); if(!ret) return MString(); unsigned char *l = ret.data + lpos + (mask ? 4 : 0); memcpy(ret.data, buf, lpos); memcpy(l, data, data); if(mask){ unsigned char *t = l + data.sz; unsigned char *ft = t - (data.sz % 4); unsigned char *m = (unsigned char*)&mask; memcpy(ret.data + lpos, &mask, 4); for(l; l < ft; l += 4) *(unsigned int*)l ^= mask; for(l; l < t; l++) *l ^= *m++; } return ret; } 

Tested at work with the client sending strings. Frames support not implemented.

Ps. Tell me, why do we need a mask? I did not understand its meaning. What exactly does it protect against?