HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Loading data from a remote app

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
apploadingremotefromdata

Problem

I have a method which loads data from a remote app (send TCP request and parse response). Now, I have a simple class for sending a TCP request:

```
public class PremieraTcpClient
{
public PremieraTcpClient()
{
QueryItems = new NameValueCollection();
int port;
int.TryParse(ConfigurationManager.AppSettings["PremieraPort"], out port);
Port = port;
ServerIp = ConfigurationManager.AppSettings["PremieraServerIp"];
ServiceId = ConfigurationManager.AppSettings["PremieraServiceId"];
}
public NameValueCollection QueryItems { get; set; }

private int Port { get; set; }

private string ServerIp { get; set; }

private string ServiceId { get; set; }

private string ReadyQuery { get; set; }

public string SendQuery()
{
StringBuilder parameters = new StringBuilder();

//...
// build query for request
//...
ReadyQuery = parameters.ToString();
return Connect();
}

private string Connect()
{
string responseData;

try
{
TcpClient client = new TcpClient(ServerIp, Port);
client.ReceiveBufferSize = Int32.MaxValue;

Byte[] data = Encoding.GetEncoding(1251).GetBytes(ReadyQuery);

NetworkStream stream = client.GetStream();

// send data
stream.Write(data, 0, data.Length);

var sizeBuffer = new byte[10];

stream.Read(sizeBuffer, 0, 10);
var sizeMessage = int.Parse(Encoding.GetEncoding(1251).GetString(sizeBuffer, 0, 10));

data = new Byte[sizeMessage];

var readSoFar = 0;
//read data
while (readSoFar < sizeMessage)
{
readSoFar += stre

Solution

I have some suggestions about PremieraTcpClient. The way it is written may lead to unreleased resources. If you have an error then you will remain with a stream and client opened.
The correct way to do it is by using try...catch...finally or by using using.
Below you can find the code using try catch finally

private string Connect()
    {
        string responseData = string.Empty;
        TcpClient client = null;
        NetworkStream stream = null; 
        try
        {
            client = new TcpClient(ServerIp, Port);
            client.ReceiveBufferSize = Int32.MaxValue;

            Byte[] data = Encoding.GetEncoding(1251).GetBytes(ReadyQuery);

            stream = client.GetStream();

            // send data
            stream.Write(data, 0, data.Length);

            var sizeBuffer = new byte[10];

            stream.Read(sizeBuffer, 0, 10);
            var sizeMessage = int.Parse(Encoding.GetEncoding(1251).GetString(sizeBuffer, 0, 10));

            data = new Byte[sizeMessage];

            var readSoFar = 0;
            //read data
            while (readSoFar < sizeMessage)
            {
                readSoFar += stream.Read(data, readSoFar, data.Length - readSoFar);
            }

            responseData = Encoding.GetEncoding(1251).GetString(data, 0, data.Length);
            responseData = responseData.TrimStart('&');
            //stream.Close();
            //client.Close();
            //return responseData;
        }
        catch (ArgumentNullException e)
        {
            //return responseData = string.Format("ArgumentNullException: {0}", e);
        }
        catch (SocketException e)
        {
            //return responseData = string.Format("SocketException: {0}", e);
        }
        finally
        {
            if(stream!=null) stream.Close();
            if(client!=null) client.Close();
        }

        return responseData;
    }


And another small suggestion: I think is misleading to have a method named Connect that in fact does more than connect. It will be better to break the Connect method into smaller methods, each one with specific actions (even if they are private).

Code Snippets

private string Connect()
    {
        string responseData = string.Empty;
        TcpClient client = null;
        NetworkStream stream = null; 
        try
        {
            client = new TcpClient(ServerIp, Port);
            client.ReceiveBufferSize = Int32.MaxValue;

            Byte[] data = Encoding.GetEncoding(1251).GetBytes(ReadyQuery);

            stream = client.GetStream();

            // send data
            stream.Write(data, 0, data.Length);

            var sizeBuffer = new byte[10];

            stream.Read(sizeBuffer, 0, 10);
            var sizeMessage = int.Parse(Encoding.GetEncoding(1251).GetString(sizeBuffer, 0, 10));

            data = new Byte[sizeMessage];

            var readSoFar = 0;
            //read data
            while (readSoFar < sizeMessage)
            {
                readSoFar += stream.Read(data, readSoFar, data.Length - readSoFar);
            }

            responseData = Encoding.GetEncoding(1251).GetString(data, 0, data.Length);
            responseData = responseData.TrimStart('&');
            //stream.Close();
            //client.Close();
            //return responseData;
        }
        catch (ArgumentNullException e)
        {
            //return responseData = string.Format("ArgumentNullException: {0}", e);
        }
        catch (SocketException e)
        {
            //return responseData = string.Format("SocketException: {0}", e);
        }
        finally
        {
            if(stream!=null) stream.Close();
            if(client!=null) client.Close();
        }

        return responseData;
    }

Context

StackExchange Code Review Q#10611, answer score: 4

Revisions (0)

No revisions yet.