TCP客户端未读取来自服务器的发送消息的一半



我有一个TCP服务器,它以以下格式发送数据

------------|--------------------------------
---Header---|  ----------- Data ----------
------------|--------------------------------

报头大小为40字节,其中前2字节表示数据长度,其余字节均为0。

当需要从服务器端传输的数据量大于1500时,服务器端按照以下方式发送数据:

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)
|--------------------

这是我从客户端服务器读取数据的过程

  1. 首先我读取头(40字节)并处理它以获得要读取的数据长度。
  2. 获取数据长度后,读取"data-length">

我面临的问题是,这个过程在我的pc上工作得很好,但当我测试其他pc时,它只在调试模式下工作(就像我每次跳过一样)。否则,它只读取消息的前半部分,丢弃后半部分,并抛出此错误。

System.Exception
HResult=0x80131500
Message=Exception occurred {0}
Source=SockTest
StackTrace:
at socketTest.sockTest.readData() in C:usrtestingSocketTransREciveSockTestsockTest.cs:line 125
at socketTest.main.testTrasRecv(sockTest sock, String command) in C:usrtestingSocketTransREciveSockTestProgram.cs:line 13
at socketTest.main.testSend() in C:usrtestingSocketTransREciveSockTestProgram.cs:line 51
at socketTest.main.Main(String[] args) in C:usrtestingSocketTransREciveSockTestProgram.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')

我不确定是什么引起了这个问题。我已经检查了wire-shark上的交易,似乎服务器正在正确发送它们。任何帮助都将非常感激!

客户机代码

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;
}

}
}

下面是注释

的实现
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;
}
}

干杯!

最新更新