Websocket Server in C++ Error on sending message - c++

I've been developing a C++ websocket server and it's working pretty good, except for one error that I don't understand.
The thing is that I can receive data and perform actions claimed by web browsers, but supposing that the server needs to send back some info, the first time it's sent succesfully, but when I repeat the same request (or another one which needs information back to browser), my server tries to send it (apparently successfully), then by itself sends it again (I don't know why) and then the connection is closed.
here's my code for sending messages:
int CSocketNode::SendMsg(const char opr, const char* cad,int length){
if (socket_conn == INVALID_SOCKET)
return -1;
int pos = 0;
int result = 0;
memset(Buffer_out, 0, BUFFER_SIZE);
if(!webSocket){
//Build header
Buffer_out[pos] = 57; //12345 % 256;
Buffer_out[pos + 1] = 48; //12345 / 256;
length++;
if((length / 256) >= 256){
int divi = length / 256;
Buffer_out[pos + 2] = length % 256;
Buffer_out[pos + 3] = divi % 256;
Buffer_out[pos + 4] = divi / 256;
} else {
Buffer_out[pos + 2] = length % 256;
Buffer_out[pos + 3] = 0;
Buffer_out[pos + 4] = length / 256;
}
Buffer_out[pos + 5] = opr;
pos = 5;
memcpy(Buffer_out + pos + 1, cad, length);
} else {
Buffer_out[pos++] = 0x81;
length++;
if(length <= 125){
Buffer_out[pos++] = length;
} else if(length <= 65535) {
Buffer_out[pos++] = 126;
Buffer_out[pos++] = (length >> 8) & 0xff;
Buffer_out[pos++] = length & 0xff;
} else {
Buffer_out[pos++] = 127;
memset(Buffer_out + pos, 0, 8);
for (int i = 7; i >= 0; i--){
Buffer_out[pos++] = (length >> 8*i) & 0xff;
}
}
Buffer_out[pos++] = opr;
memcpy(Buffer_out + pos, cad, length);
}
printf("0: %d, 1: %d, 2: %d, 3: %d, 4: %d. Pos = %d\n", Buffer_out[0], Buffer_out[1], Buffer_out[2], Buffer_out[3], Buffer_out[4], pos);
printf("%s\n", Buffer_out + pos);
result = SendBytes(Buffer_out, length + pos);
return result;
}
int CSocketNode::SendBytes(char *cad, int length){
//Send it
int err = send(socket_conn, cad, length,0);
if (err == SOCKET_ERROR ){
Error("SendBytes Error");
return -1;
}
return 0;
}
The first part of the IF sentence is for my non web browser clients, which works perfectly.
no matter what size the data frame is, less than 125 or less than 65535, the result is the same.
maybe I'm missing something. Maybe I havve to add and a FIN message at the wnd of the message. but according to the WebSocket Manual, it is the first bit of the message which indicates if it's the or not of multiple messages.
If you can tell me what it is I will be very thankful.

Solved it by myself. For some reason that I cannot guess, the memcpy makes the socket pipe not work correctly.
So I used a for loop to copy the message to the buffer. And solved.

Related

mysql_stmt_fetch_column(), how to use non-zero offset

Has anyone successfully used mysql_stmt_fetch_column() with offset > 0?
The non-zero offset appears to have no effect in the following:
if (length[i] == 0) break;
if (StrBufLen == 0)
{
int cnt = StrBlobLen, retval;
(**results).elt[row * cols + i] = LVStr((char*) str[i].c_str(), min<int>(length[i], StrBlobLen));
while (cnt < length[i])
{
if ((retval = mysql_stmt_fetch_column(api.my.stmt, api.my.bind, i, cnt)) != 0)
{errnum = retval; errstr = mysql_error(api.my.con); return -1;}
LV_str_cat((**results).elt[row * cols + i], (char*) str[i].c_str(), min<int>(length[i] - cnt, StrBlobLen));
cnt += StrBlobLen;
}
}
I looked at the source for libmysql.cc and found these lines (2818):
char *start = value + param->offset;
char *end = value + length;
I suspect it should be:
char *start = value + param->offset;
char *end = start + length;
My offset is the length of the buffer, so the function would appear to copy zero bytes on the second call.

Qt serial port communication from an input file; weird behavior

I am working on programming a device using Qt C++ 5.3.2.
There is a weird behavior, which I am not able to understand.
QByteArray file_data;
if (!file.atEnd()) {
file_data = file.readAll();
}
int i = 0, j = 0;
int index = 0;
QByteArray DataBuf;
j = 76;
while (true)
{
DataBuf[0] = (j + 3);
DataBuf[1] = 0x24;
DataBuf[2] = 0x24;
for (i = 0; i < j; ++i)
{
DataBuf[i + 3] = file_data[i + index];
DataBuf[1] = DataBuf[1] + file_data[i + index]; //Doubt here
}
response.clear();
serialPort->write(DataBuf, DataBuf[0]);
for (int i=0;i<6;i++) {
if (serialPort->readBufferSize()>=2) {
break;
}
wait(1); //user defined function, is same as msleep(5)
}
qa = response.toLocal8Bit();
if (qa.toHex() != "00cc") return;
index += 76;
if (j == len) break;
if (len > 76) len -= 76;
if (len <= 76) j = len;
}
This is the part of code which I am working on. The line mentioned as " Doubt here" does not work as expected.
When I run this program the value at Databuf[1] does not match the sum of the total 76 bytes of data.
The data written in Databuf[2] to Databuf[78] is totally correct, but the addition is not.
But when I change the line from DataBuf[1] = DataBuf[1] + file_data[i + index]; to DataBuf[1] = DataBuf[1] + DataBuf[i + 3]; it works properly.
What is happening here? Can anyone help please.

Websocket Poco can't receive big data

I downloaded and built Poco project from Poco and run WebsocketServer project in poco-1.7.6\Net\samples\WebSocketServer.
When I worked with small data that is smaller 128 KB (131072 bytes), it work perfectly. But if I work with bigger data (I need to send 20 MB), my data will be cut so server don't receive data enough.
Here is code that I copy in project:
WebSocket ws(request, response);
char *buffer = new char[1000000]; // It just receive 131072 bytes
int flags;
int n;
do
{
n = ws.receiveFrame(buffer, sizeof(buffer), flags);
ws.sendFrame(buffer, tmp.length(), flags);
} while (n > 0 || (flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE);
delete[] buffer;
Deframe code:
int WebSocketImpl::receiveBytes(void* buffer, int length, int)
{
char header[MAX_HEADER_LENGTH];
int n = receiveNBytes(header, 2);
if (n <= 0)
{
_frameFlags = 0;
return n;
}
poco_assert (n == 2);
Poco::UInt8 lengthByte = static_cast<Poco::UInt8>(header[1]);
int maskOffset = 0;
if (lengthByte & FRAME_FLAG_MASK) maskOffset += 4;
lengthByte &= 0x7f;
if (lengthByte > 0 || maskOffset > 0)
{
if (lengthByte + 2 + maskOffset < MAX_HEADER_LENGTH)
{
n = receiveNBytes(header + 2, lengthByte + maskOffset);
}
else
{
n = receiveNBytes(header + 2, MAX_HEADER_LENGTH - 2);
}
if (n <= 0) throw WebSocketException("Incomplete header received", WebSocket::WS_ERR_INCOMPLETE_FRAME);
n += 2;
}
Poco::MemoryInputStream istr(header, n);
Poco::BinaryReader reader(istr, Poco::BinaryReader::NETWORK_BYTE_ORDER);
Poco::UInt8 flags;
char mask[4];
reader >> flags >> lengthByte;
_frameFlags = flags;
int payloadLength = 0;
int payloadOffset = 2;
if ((lengthByte & 0x7f) == 127)
{
Poco::UInt64 l;
reader >> l;
if (l > length) throw WebSocketException(Poco::format("Insufficient buffer for payload size %Lu", l), WebSocket::WS_ERR_PAYLOAD_TOO_BIG);
payloadLength = static_cast<int>(l);
payloadOffset += 8;
}
else if ((lengthByte & 0x7f) == 126)
{
Poco::UInt16 l;
//lenBuffer = l;
if (l > length) throw WebSocketException(Poco::format("Insufficient buffer for payload size %hu", l), WebSocket::WS_ERR_PAYLOAD_TOO_BIG);
payloadLength = static_cast<int>(l);
payloadOffset += 2;
}
else
{
Poco::UInt8 l = lengthByte & 0x7f;
if (l > length) throw WebSocketException(Poco::format("Insufficient buffer for payload size %u", unsigned(l)), WebSocket::WS_ERR_PAYLOAD_TOO_BIG);
payloadLength = static_cast<int>(l);
}
if (lengthByte & FRAME_FLAG_MASK)
{
reader.readRaw(mask, 4);
payloadOffset += 4;
}
int received = 0;
if (payloadOffset < n)
{
std::memcpy(buffer, header + payloadOffset, n - payloadOffset);
received = n - payloadOffset;
}
if (received < payloadLength)
{
n = receiveNBytes(reinterpret_cast<char*>(buffer) + received, payloadLength - received);
if (n <= 0) throw WebSocketException("Incomplete frame received", WebSocket::WS_ERR_INCOMPLETE_FRAME);
received += n;
}
if (lengthByte & FRAME_FLAG_MASK)
{
char* p = reinterpret_cast<char*>(buffer);
for (int i = 0; i < received; i++)
{
p[i] ^= mask[i % 4];
}
}
return received;
}
Can anyone help me, please!
P/s: Sorry about my English
UPDATE: I just got this problem in Chrome. It work fine with Firefox and Edge
Setting setChunkedTransferEncoding should make it work.
In the code before the response is sent set:
response.setChunkedTransferEncoding(true);

What's wrong with this parallel algorithm?

I'm trying to write parallel algorithm in openCL for L-system Pythagoras Tree :
var:A,B;
const: (,);
axiom:A;
rules:(B->BB),(A->B[A]A)
But i can't get over 9th iteration. 10th iteration returns disordered string. Here is my kernel:
#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable
#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable
#pragma OPENCL EXTENSION cl_amd_printf : enable
__kernel void l_system(int string_lenght){}
__kernel void l_system_interation(int string_lenght, __global char *sentence, __local char *string, __global int * local_char_num)
{
int local_x = (int)get_local_id(0);
int local_size = (int)get_local_size(0);
int x = (int)get_global_id(0);
int size = (int)get_global_size(0);
int group = (int)get_group_id(0);
int local_mem_index;
if(x < string_lenght){
//local mem index - offset for next group, copy char to local
local_mem_index = local_x * 5;
string[local_mem_index] = sentence[x];
if(local_x == 0){
//reset counter
atomic_xchg(&local_char_num[group], 0);
//atomic_add(&local_char_num[0], group);
}
}
barrier(CLK_LOCAL_MEM_FENCE);
barrier(CLK_GLOBAL_MEM_FENCE);
if(x < string_lenght){
if(string[local_mem_index] == 'A'){
atomic_add(&local_char_num[group], 5);
string[local_mem_index] = 'B';
string[local_mem_index + 1] = '(';
string[local_mem_index + 2] = 'A';
string[local_mem_index + 3] = ')';
string[local_mem_index + 4] = 'A';
}
else if(string[local_mem_index] == 'B'){
atomic_add(&local_char_num[group], 2);
string[local_mem_index + 1] = 'B';
//reset 3rd char of local_mem
string[local_mem_index + 2] = '0';
}
else{
atomic_add(&local_char_num[group], 1);
//reset 3rd char of local_mem
string[local_mem_index + 2] = '0';
string[local_mem_index + 2] = '0';
}
}
barrier(CLK_LOCAL_MEM_FENCE);
barrier(CLK_GLOBAL_MEM_FENCE);
//1 compute unit for every char from src
if(x < string_lenght){
//local first compute unit writes to result whole group string
if(local_x == 0){
int j = 0;
//find offset for write to result string
if(x != 0){
for(int l = 1;l <= group; l++)
{
j += atomic_xchg(&local_char_num[group-l], local_char_num[group-l]);
//if(l == 0)
}
atomic_xchg(&local_char_num[99+group], local_char_num[group]);
}
for(int i = 0; i < local_size; i++){
//only valid chars
if(string_lenght > (x+i)){
local_mem_index = i * 5;
//B rule, copy (,)
if(string[local_mem_index+2] != 'A'){
sentence[j++] = string[local_mem_index];
if(string[local_mem_index] == 'B'){
sentence[j++] = string[local_mem_index+1];
}
continue;//B,(,); next index;
}
else{ // A rule
sentence[j++] = string[local_mem_index];
sentence[j++] = string[local_mem_index+1];
sentence[j++] = string[local_mem_index+2];
sentence[j++] = string[local_mem_index+3];
sentence[j++] = string[local_mem_index+4];
}//if 'A'
//sentence[j] = 0;
}//if x+i
}//for
}// lx == 0
}
barrier(CLK_GLOBAL_MEM_FENCE);
}
I think, that something overflow anywhere, but can't find where... Maybe there is something wrong with my code in main:
cl_int letter_count = 0;
cl_int next_letter_count = 1;
for (int i = 0; i < iter_count; i++)
{
//printf("%s\n", sentence_init);
letter_count = next_letter_count;
next_letter_count = STRING_LENGTH_PAR((i + 1));
printf("in count: %d out count: %d\n", letter_count, next_letter_count);
CheckOpenCLError(clSetKernelArg(kernel_iteration, 0, sizeof(cl_int), &letter_count), "clSetKernelArg: letter_count");
CheckOpenCLError(clSetKernelArg(kernel_iteration, 2, sizeof(cl_char)* (local * RULE_SIZE + 1), NULL), "clSetKernelArg: tmp_string");
CheckOpenCLError(clEnqueueNDRangeKernel(queue, kernel_iteration, 1, NULL, &global, &local, 0, NULL, &kernel_iteration_event), "clEnqueueNDRangeKernel: kernel_iteration");
CheckOpenCLError(clFinish(queue), "clFinish");
kernel_computing_time += getEventTime(kernel_iteration_event);
}
CheckOpenCLError(clEnqueueReadBuffer(queue, sentence_dev, CL_TRUE, 0, sizeof(cl_char)* (next_letter_count), sentence_result, 0, NULL, &result_iteration_event), "clEnqueueReadBuffer: result_iteration_event");
cl_int *p = (cl_int*)malloc(sizeof(cl_int)*(STRING_LENGTH_PAR(iter_count)));
CheckOpenCLError(clEnqueueReadBuffer(queue, p_dev, CL_TRUE, 0, sizeof(cl_int)* (STRING_LENGTH_PAR(iter_count)), p, 0, NULL, &result_iteration_event), "clEnqueueReadBuffer: result_iteration_event");

ICMP Checksum error

I am trying to checksum icmp packet using the same technique for tcp and udp but it get wrong checksum, can you tell me where is my problem ?
ICMP_HEADER *icmpheader = new ICMP_HEADER;
memcpy(icmpheader,ICMPHeader,sizeof(ICMP_HEADER));
icmpheader->Checksum = 0;
PSEUDO_HEADER *psheader = new PSEUDO_HEADER;
memcpy(&psheader->daddr, &IPHeader->DestinationAddress, sizeof(UINT));
memcpy(&psheader->saddr, &IPHeader->SourceAddress, sizeof(UINT));
psheader->protocol = IPHeader->Protocol;
psheader->length = htons((USHORT)(sizeof(ICMP_HEADER) + ICMPDataSize));
psheader->zero = 0x0000;
UINT packet_size = sizeof(ICMP_HEADER) + ICMPDataSize + sizeof(PSEUDO_HEADER);
packet_size = packet_size + ((packet_size%2)*2);
UCHAR *icmppacket = (UCHAR*)malloc(packet_size);
memset(icmppacket,0, packet_size);
memcpy(icmppacket, psheader, sizeof(PSEUDO_HEADER));
memcpy(&icmppacket[sizeof(PSEUDO_HEADER)], icmpheader,sizeof(ICMP_HEADER));
memcpy(&icmppacket[sizeof(PSEUDO_HEADER) + sizeof(ICMP_HEADER)],ICMPData,ICMPDataSize);
if (GlobalChecksum((USHORT*)icmppacket,packet_size) != ICMPHeader->Checksum)
{
isMalformed = true;
PacketError = PACKET_ICMP_CHECKSUM;
}
USHORT cPacket::GlobalChecksum(USHORT *buffer, UINT length)
{
register int sum = 0;
USHORT answer = 0;
register USHORT *w = buffer;
register int nleft = length;
while(nleft > 1){
sum += *w++;
nleft -= 2;
}
sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);
answer = ~sum;
return(answer);
}
solved it by removing pseudo header and calculating icmp header and icmp data only
ICMP_HEADER *icmpheader = new ICMP_HEADER;
memcpy(icmpheader,ICMPHeader,sizeof(ICMP_HEADER));
icmpheader->Checksum = 0x0000;
UINT packet_size = sizeof(ICMP_HEADER) + ICMPDataSize;
packet_size = packet_size + ((packet_size%2)*2);
UCHAR *icmppacket = (UCHAR*)malloc(packet_size);
memset(icmppacket,0, packet_size);
memcpy(icmppacket, icmpheader,sizeof(ICMP_HEADER));
memcpy(&icmppacket[sizeof(ICMP_HEADER)],ICMPData,ICMPDataSize);
if (GlobalChecksum((USHORT*)icmppacket,packet_size) != ICMPHeader->Checksum)
{
isMalformed = true;
PacketError = PACKET_ICMP_CHECKSUM;
}