Socket Asynchronous C# receiving more than one message at a time

Asked

Viewed 103 times

1

I am developing a C# Dll that works with Socket TCP Asynchronous for the development of some tools I am working on, the problem appears when the client receives many messages in a short period, in this case the messages are in JSON, Therefore, the server sends me only one JSON message to watch, but the client receives 2 or 3 together, causing an Exception when trying to turn JSON into Object. Being that if I send the server a message every second, everything goes well, but my system depends on more messages per second.
NOTE: Server is done in C++ with QT.

CLIENT:

    public void connect(Action<Message> callback, string ip, int porta){
        this.callback = callback;
        this.ip = ip;
        this.porta = porta;
        try{
            this.ipadress = new IPEndPoint (IPAddress.Parse (this.ip), this.porta);
            this.client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
            this.client.BeginConnect (this.ipadress, new AsyncCallback (ConectCallback), null);
        }catch(Exception ex){
            this.conected = false;
            lastExeception = ex;
        }
    }
    void ReceiveCallback(IAsyncResult IA){
        String json_string = "";
        if (isConnected ()) {
            try {
                int received = client.EndReceive (IA);
                Array.Resize (ref _buffer, received);
                json_string = Encoding.UTF8.GetString (_buffer);

                Console.WriteLine(json_string);

                Message msg = JsonConvert.DeserializeObject<Message> (json_string);
                callback_sender (msg);

                Array.Resize (ref _buffer, client.ReceiveBufferSize);
                if (isConnected ())
                    client.BeginReceive (_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback (ReceiveCallback), null);
            } catch (JsonException erro) {
                lastExeception = erro;
            } catch (Exception ex) {
                lastExeception = ex;
            }
        }
    }

SERVER:

void MyClient::readyRead() {
   qDebug() << "MyClient::readyRead()";
   QString msg = socket->readAll();
   qDebug() << msg;
   socket->write(msg.toUtf8());
}

1 answer

0

I solved my problem as follows, as I always received several Jsons together, I checked if there was the end and start of the keys, if yes, I transformed the simple JSON into a List, and so I was able to receive everything without Exception.

void ReceiveCallback(IAsyncResult IA){
        String json_string = "";
        if (isConnected ()) {
            try {
                int received = client.EndReceive (IA);
                Array.Resize (ref _buffer, received);
                json_string = Encoding.UTF8.GetString (_buffer);

                if(json_string.Contains("}{")){ // verifica se existe mais de um JSON na String
                    json_string = json_string.Replace("}{","},{"); // transforma em Array de JSON
                }
                json_string = "["+json_string+"]"; // finaliza o array com colchetes para não ocorrer erro

                List<Message> msg = JsonConvert.DeserializeObject<List<Message>> (json_string); // Transforma a string JSON e lista de Objeto
                foreach(Message m in msg){ // pega todos os objetos da lista
                    callback_sender(m);
                }

                Array.Resize (ref _buffer, client.ReceiveBufferSize);
                if (isConnected ())
                    client.BeginReceive (_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback (ReceiveCallback), null);
            } catch (JsonException erro) {
                lastExeception = erro;
            } catch (Exception ex) {
                lastExeception = ex;
            }
        }
    }

Browser other questions tagged

You are not signed in. Login or sign up in order to post.