I have a TCP server which send the data in the below format
------------|--------------------------------
---Header---| ----------- Data ----------
------------|--------------------------------
Header is of size 40 bytes of which first 2 bytes signifies the Data length and all the remaining bytes are 0 .
When the size of the data that needs to transfer from the server end is greater than 1500 the server sends the data in the following manner.
example: if length(data) == 1597
first transaction ->
-------|--------------------
|Header| data of length 1460
-------|--------------------
second transaction ->
|--------------------
data of length 147 (Note this transaction doesn't have header)
|--------------------
This is the process I'm following to read the data from the server on client end
The problem I'm facing is that this process works fine in my pc but when i test this other pcs it only works in debug mode (like when i step over each time). Other it only reads the first half of the message and discards the next part and throws this error.
System.Exception
HResult=0x80131500
Message=Exception occurred {0}
Source=SockTest
StackTrace:
at socketTest.sockTest.readData() in C:\usr\testing\SocketTransREcive\SockTest\sockTest.cs:line 125
at socketTest.main.testTrasRecv(sockTest sock, String command) in C:\usr\testing\SocketTransREcive\SockTest\Program.cs:line 13
at socketTest.main.testSend() in C:\usr\testing\SocketTransREcive\SockTest\Program.cs:line 51
at socketTest.main.Main(String[] args) in C:\usr\testing\SocketTransREcive\SockTest\Program.cs:line 63
This exception was originally thrown at this call stack:
[External Code]
socketTest.sockTest.readData() in sockTest.cs
Inner Exception 1:
ArgumentOutOfRangeException: Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection. (Parameter 'count')
I'm not sure what is causing the issue. I have checked the transactions on wire-shark and it seems server is sending them properly. Any help would be really appreciated!
Client Code
namespace socketTest
{
using System;
using System.Net;
using System.Net.Sockets;
public class sockTest : IDisposable
{
// defaults
private string ip = "192.168.1.100";
private int port = 1234;
//private int port = 16666;
public int error = -1;
public int noError = 0;
bool disposed = false;
private byte[] buffer;
private byte[] header;
// updated once instanciated
private IPAddress Ip;
public TcpClient socketHandle;
public NetworkStream tcpStream;
// instance check
private static readonly Lazy<sockTest> lazy = new Lazy<sockTest>(() => new sockTest());
private sockTest()
{
try
{
Console.WriteLine("Program started !");
this.Ip = IPAddress.Parse(ip);
}
catch (Exception exception)
{
//throw new Exception("Could not initialize socket erro : {0}", exception);
Console.WriteLine("Could not initialize socket error: {0}", exception);
}
}
public static sockTest Instance
{
get
{
return lazy.Value;
}
}
public int connect()
{
try
{
this.socketHandle = new TcpClient();
this.buffer = new byte[4000];
this.header = new byte[10];
this.socketHandle.Connect(this.Ip, this.port);
this.tcpStream = socketHandle.GetStream();
return noError;
}
catch (Exception exception)
{
Console.WriteLine(exception.ToString());
return error;
}
}
public int prcessHeader(byte[] header)
{
int ind = 0;
int flag = 0;
for (int i = 0; i < 10; i = i + 2)
{
int value = (header[i + 0]) | (header[i + 1] << 8);
if(flag == 0)
{
ind = value;
flag = 1;
}
}
return ind;
}
public string readData()
{
try
{
tcpStream.Read(this.header, 0, 10);
var inputString = System.Text.Encoding.ASCII.GetString(this.header);
//int msg_len = Int32.Parse(inputString);
int msg_len = prcessHeader(this.header);
tcpStream.Read(this.buffer, 0, msg_len);
return System.Text.Encoding.ASCII.GetString(this.buffer);
}
catch (Exception exception)
{
throw new Exception("Exception occurred {0}", exception);
//return null;
}
}
public int sendData(string data)
{
try
{
byte[] bData = System.Text.Encoding.ASCII.GetBytes(data);
tcpStream.Write(bData, 0, bData.Length * sizeof(byte));
return noError;
}
catch (Exception exception)
{
return error;
}
}
public void closeConnection()
{
tcpStream.Close();
this.socketHandle.Close();
}
public void Dispose()
{
// Dispose of unmanaged resources.
this.CheckDispose(true);
// Suppress finalization.
GC.SuppressFinalize(this);
}
protected virtual void CheckDispose(bool disposing)
{
if (disposed)
return;
if (disposing)
{
this.closeConnection();
}
disposed = true;
}
}
}
Here is the implementation of the comment
public string readData()
{
try
{
string tempRecv = "";
int len_read_msg = 0;
tcpStream.Read(this.header, 0, 10);
// your header parsing logic
int msg_len = processHeader(this.header);
if (msg_len > 1024)
{
len_read_msg = 1024;
}
else
{
len_read_msg = msg_len;
}
int tempRead = 0;
int compRead = 0;
while (compRead < msg_len)
{
Array.Clear(this.buffer, 0, this.buffer.Length);
tempRead = tcpStream.Read(this.buffer, 0, len_read_msg);
compRead = compRead + tempRead;
len_read_msg = msg_len - compRead;
var encoded = System.Text.Encoding.ASCII.GetString(this.buffer).Trim();
}
return tempRecv;
}
catch (Exception exception)
{
//throw new Exception("Exception occurred {0}", exception);
return null;
}
}
Cheers!