2016-04-14 58 views
2

我有一个多线程TCP套接字侦听器程序。我对一个特定的字节数(128字节和4x多个)的数据进行了阻塞读取,所以我的数据包大小是128字节,256字节,384字节和512字节。TCP套接字数据获取加扰

我有问题,因为有时候数据在插座中变得混乱。对于如:

应该阅读:

<header><data payload(padded with zeros to compensate size)><footer> 

ex-- ABCDddddddddd0000000000WXYZ

我有时读什么:

ex-- ABCDdd00000000000000000dddddd00

,然后下一个数据包看起来像

00000WXYZABCDddddd00000000000000000

,所以我关闭套接字,我们已经定义了协议来发送回2个或3旧数据包,以避免损失。

我的问题是

1.为何数据得到炒/搞砸?

2.是否可以通过任何方式避免?

这里是我读取数据的代码。

in = new DataInputStream(conn.getInputStream()); 
outStream = conn.getOutputStream(); 
while (m_bRunThread) { 
    // read incoming stream 
    in.readFully(rec_data_in_byte, 0, 128); //blocks until 128 bytes are read from the socket 
    { 
     //converting the read byte array into string 
     //finding out the size from a particular position,helps determine if any further reads are required or not. 
     //if the size is a multiple of 128 and the size is a multiple higher than 1 then more reads are required. 
     if ((Integer.parseInt(SIZE) % 128 == 0) && ((SIZE/128) > 1)) { 
      for(int z = 1;z < lenSIZE;z++) { 
       in.readFully(rec_data_in_byte1, 0, 128);//changed from in.read(rec_data_in_byte1, 0, 128); as per suggestions 
      } 
      //extracting the data,validating and processing it 
     } 
    } 
} 

UPDATE: 实现彼得斯修复,但问题仍然存在。数据越来越乱。 在字节数组转换为字符串的地方添加几行额外的代码。

byte[] REC_data=new byte[1024]; 
System.arraycopy(rec_data_in_byte1, 0, REC_data, 128*z, 128); 
rec_data_string=MyClass2.getData(REC_data,0,Integer.parseInt(SIZE)-1,Integer.parseInt(SIZE)); 

的getData()方法是如下:

String msg = "";//the return String 
    int count = 1; 
    for (int i = 0; i < datasize; i++) { 
     if (i >= startindex) { 
      if (count <= lengthofpacket) { 
       msg += String.valueOf((char) (bytedata[i])); 
       count++; 
      } 
     } 
    } 
    return msg; 

可以任何这是用于加扰的原因吗?

P.S - 争夺的方式与之前发生的一样。

+2

我回滚了上次的编辑。您的修改使Peter Lawrey给出的答案失效。如果你遵循了彼得的建议,那么要么提出一个新问题,要么更新你的问题来**添加**你尝试过的新事物和你所看到的。请注意,您应该也包含用于编写数据的代码。问题可能就在那里。 –

+0

@Mark Rotteveel-感谢您的建议。将从现在开始做。新的到stackoverflow的世界.. –

+0

所有的更新和回滚后,你仍然有一个'read()'方法的返回值,你没有使用。你需要在任何地方使用'readFully()',或者不要假设'read()'填充缓冲区的适当代码。 TCP是一个字节流,没有义务一次传送多个字节。 – EJP

回答

2

当你

int lengthActuallyRead = in.read(rec_data_in_byte1, 0, 128); 

您需要检查读取的长度。否则,它可能会读取1个字节,或者在这种情况下读取最多128个字节。请注意,实际读取的内容之后的任何字节都是未触及的,因此它们可能是0,或者它们可能是垃圾留在先前的消息中。

如果你希望128个字节你可以使用readFully像你一样以前

in.readFully(rec_data_in_byte, 0, 128); 

注意:如果剩余量小于128你可能想这样做。

int remaining = size - sizeReadSoFar; 
int length = in.read(rec_data_in_byte1, 0, remaining); 

这会阻止您在阅读旧信息时阅读下一部分信息。

+0

我的协议是设计在客户端发送数据包只有128字节和多达4,所以读取的数据将永远是128和它的倍数。现在编辑代码现在**读**现在是**读**,所以它的目的。 –

+0

但仍然是我的问题仍然可以数据混乱/杂乱? –

+0

@JayeshTripathi数据在网络上没有损坏,但是如果你没有正确读取它,它可能会被损坏。 –