BOOL CWebSocketProtocol::WritePacket76(CConnectionSession<CWebSocketProtocol> &pConn, BYTE *data, DWORD dataLength) { if (!data || dataLength <= 0) return FALSE; //v76版协议包装 BYTE TempBuffer[MAX_PACKET_BUFFER_LENGTH]; TempBuffer[0] = 0x81; if (dataLength < 126) { BYTE TempLength = (BYTE)dataLength; CopyMemory(TempBuffer+1, &TempLength, 1); CopyMemory(TempBuffer+2, data, dataLength); return pConn.WritePacket(TempBuffer, dataLength+2); } else if (dataLength < USHRT_MAX) { BYTE TempLength = 126; USHORT shortLength = htons((USHORT)dataLength); CopyMemory(TempBuffer+1, &TempLength, 1); CopyMemory(TempBuffer+2, &shortLength, sizeof(USHORT)); CopyMemory(TempBuffer+2 + sizeof(USHORT), data, dataLength); return pConn.WritePacket(TempBuffer, dataLength+2 + sizeof(USHORT)); } else { BYTE TempLength = 127; DWORD64 Len64 = NTOH64((DWORD64)dataLength); CopyMemory(TempBuffer+1, &TempLength, 1); CopyMemory(TempBuffer+2, &Len64, sizeof(DWORD64)); CopyMemory(TempBuffer+2 + sizeof(DWORD64), data, dataLength); return pConn.WritePacket(TempBuffer, dataLength+2 + sizeof(DWORD64)); } return FALSE; }
void pgsql_store_binary(int32 idlType, int16 isarray, char *input, UCHAR *output) { switch(idlType) { case IDL_TYP_FLOAT: /* atof actually returns double */ if (isarray) fillNumArray(input, output, 4); else NTOH32(input, output); break; case IDL_TYP_DOUBLE: if (isarray) fillNumArray(input, output, 8); else NTOH64(input, output); break; case IDL_TYP_BYTE: if (isarray) fillNumArray(input, output, 1); else *(UCHAR *) output = *(UCHAR *) input; break; case IDL_TYP_INT: if (isarray) fillNumArray(input, output, 2); else NTOH16(input, output); break; case IDL_TYP_UINT: if (isarray) fillNumArray(input, output, 2); else NTOH16(input, output); break; case IDL_TYP_LONG: if (isarray) fillNumArray(input, output, 4); else NTOH32(input, output); break; case IDL_TYP_ULONG: if (isarray) fillNumArray(input, output, 4); else NTOH32(input, output); break; case IDL_TYP_LONG64: if (isarray) fillNumArray(input, output, 8); else NTOH64(input, output); break; case IDL_TYP_ULONG64: if (isarray) fillNumArray(input, output, 8); else NTOH64(input, output); break; case IDL_TYP_STRING: if (isarray) fillStringArray(input, (IDL_STRING *) output); else IDL_StrStore( (IDL_STRING *) output, input); break; default: printf("Unsupported type %d found\n", idlType); fflush(stdout); break; } }
void fillNumArray(char *mem, UCHAR* array, int32 nbytes) { //char *memptr, *arrptr; UCHAR* memptr; UCHAR* arrptr; int i, n_elements; memptr = (UCHAR *) mem; arrptr = (UCHAR *) array; /* skip some elements to get to data */ memptr += 3*SIZE32; /* get number of elements */ n_elements = ntohl( *(int32 *) memptr ); memptr += 2*SIZE32; switch(nbytes) { case 1: for (i=0; i< n_elements; i++) { /* Need to skip an int, which is size of this array element */ /* This is always same for float32 */ memptr += SIZE32; *arrptr = *memptr; /* next element */ memptr += nbytes; arrptr += nbytes; } break; case 2: for(i=0; i<n_elements; i++) { /* Need to skip an int, which is size of this array element */ /* This is always same for float32 */ memptr += SIZE32; /* copy in converted to host */ NTOH16(memptr, arrptr); /* next element */ memptr += nbytes; arrptr += nbytes; } break; case 4: for(i=0; i<n_elements; i++) { /* Need to skip an int, which is size of this array element */ /* This is always same for float32 */ memptr += SIZE32; /* copy in converted to host */ NTOH32(memptr, arrptr); /* next element */ memptr += nbytes; arrptr += nbytes; } break; case 8: for(i=0; i<n_elements; i++) { /* Need to skip an int, which is size of this array element */ /* This is always same for float32 */ memptr += SIZE32; /* copy in converted to host */ NTOH64(memptr, arrptr); /* next element */ memptr += nbytes; arrptr += nbytes; } break; default: printf("nbytes must be 2,4, or 8\n"); fflush(stdout); break; } }
BOOL CWebSocketProtocol::GetPacket76(CConnectionSession<CWebSocketProtocol> &pConn, DWORD64 &packetLength) { if (mRemainLength < 6) return FALSE; DWORD64 PacketLength = 0; UCHAR opCode = mDataBuffer[0] & 0x0F; if (opCode != OP_TEXT) { //目前只处理文本消息 if (opCode == OP_CLOSE) { pConn.End(); } mRemainLength = 0; return FALSE; } if (!(mDataBuffer[0] & 0x80)) { mRemainLength = 0; ZeroMemory(mDataBuffer, MAX_PACKET_BUFFER_LENGTH); return FALSE; //多帧消息,暂不处理 } if(!(mDataBuffer[1] & 0x80)) //没有掩码, 暂不处理 { mRemainLength = 0; ZeroMemory(mDataBuffer, MAX_PACKET_BUFFER_LENGTH); return FALSE; } PacketLength = mDataBuffer[1] & 0x7F; BYTE Masks[4] = {0,}; DWORD64 TotalPacketLength; DWORD MaskOffset = 2; if (PacketLength < 126) { TotalPacketLength = PacketLength + 6; } else if (PacketLength == 126) { MaskOffset = 4; CopyMemory(&PacketLength, mDataBuffer+2, 2); //如果长度=126,那么后面2字节才是帧数据的真实长度 PacketLength = ntohs((USHORT)PacketLength); //Big Endian转换 TotalPacketLength = PacketLength + 8; //完整数据包长度 } else if (PacketLength == 127) { MaskOffset = 10; CopyMemory(&PacketLength, mDataBuffer+2, 8); //如果长度=127,那么后面8字节才是帧数据的真实长度 PacketLength = NTOH64(PacketLength); TotalPacketLength = PacketLength + 14; //基本上因为缓冲区的原因,不支持这么长的数据包,PASS } if (PacketLength < 0 || TotalPacketLength > MAX_PACKET_BUFFER_LENGTH) { //如果数据包长度超出缓冲区长度或者小于0,认为是错误的包,扔掉 mRemainLength = 0; ZeroMemory(mDataBuffer, MAX_PACKET_BUFFER_LENGTH); return FALSE; } //如果已接收数据长度>包长度,表示已经收到一个完整的包 if (TotalPacketLength <= mRemainLength) { //复制掩码,复制数据 CopyMemory(Masks, mDataBuffer+MaskOffset, 4); CopyMemory(mPacketBuffer, mDataBuffer+MaskOffset+4, (size_t)PacketLength); //使用掩码解密数据 for (INT i=0; i<PacketLength; i++) mPacketBuffer[i] = mPacketBuffer[i] ^ Masks[i % 4]; packetLength = PacketLength; //如果缓冲区还有剩下的内容,那么把剩下的往前移 if(mRemainLength - TotalPacketLength > 0) { MoveMemory(mDataBuffer, mDataBuffer + (size_t)TotalPacketLength, mRemainLength-(DWORD)TotalPacketLength); } mRemainLength -= (DWORD)TotalPacketLength; //重设缓冲区 if (mRemainLength <= 0) { mRemainLength = 0; ZeroMemory(mDataBuffer, sizeof(mDataBuffer)); } return TRUE; } return FALSE; }