添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

socket 异步接收数据时,前一个数据包没有接收完中间插了另外一个数据包该怎么处理。

问题是BeginReceive接收数据的长度怎么控制,或者接收到的数据该怎么处理

比如说前一个数据集有效长度1000byte分10次发送过来每次发送100byte,在发送到第5次时第六条数据是另外一个数据集这个数据集有效长度时30byte,如果BeginReceive接受长度时100的话在第6条数据中就有70byte是第一个数据集中的数据。这时该怎么处理?

请各位高人指点,先谢了


pinkbull

之前做个这块稍微有点经验,简单提个建议。

1.首先如果您需要分段发送大量数据的话。建议您自己定义一个发送和接受的协议。在每次发送数据时定义一个固定长度的头部数据。

它可能会包含(此次发送数据的总长度,此次发送数据的序号,或者是否是最后一个分段数据等。) 这种类似的标识信息。

之后接收方在接受固定数据长度的情况下,接收数据然后组合每次接收到数据的位置。最终组成整个数据。如果您发送的数据量不是太大,并且不太要求速率的情况下可能需要考虑每次发送的数据总量要小于路由器的MTU值,这样避免路由器在接收到数据时进行分段重组。这是一种方式。

2.如果是不固定接受的数据长度的话。实现到是可以实现,但是不能应用于大数据量。

这是之前写的一个方法,可以参考一下:)

/// <summary> /// 同步(阻塞)方式接收来自远程发来的数据,此方法会做数据分片合并操作。会一次返回远程发来的数据,无论多大。 /// </summary> /// <returns>接收到的数据</returns> public virtual ReceivedResult Receive() int availableCount = 0; int receiveCount = 0; byte[] data = null; TimeSpan pastSpan = TimeSpan.FromTicks(DateTime.Now.Ticks); while (this.socket.Available < 1) {

//判断是否超出接受超时限定 if ((this.receiveTimeout > 0) && ((TimeSpan.FromTicks(DateTime.Now.Ticks).Subtract(pastSpan).Seconds * 1000) > this.receiveTimeout)) break; Thread.Sleep(10); int cavailable = this.socket.Available; availableCount += cavailable; byte[] cdata = new byte[cavailable]; int creceive = this.socket.Receive(cdata); if (creceive < 1) break; receiveCount += creceive; if (availableCount.Equals(cavailable)) data = cdata; byte[] odata = cdata; data = new byte[availableCount]; if (null != odata) odata.CopyTo(data, 0); cdata.CopyTo(data, odata.Length); while (this.socket.Available > 0); catch (Exception) if (null != this.OnPreReceived) this.OnPreReceived(data); return new ReceivedResult() Data = data State = this.computeReceivedResult(null == data ? 0 : data.Length, receiveCount)

之前做个这块稍微有点经验,简单提个建议。

1.首先如果您需要分段发送大量数据的话。建议您自己定义一个发送和接受的协议。在每次发送数据时定义一个固定长度的头部数据。

它可能会包含(此次发送数据的总长度,此次发送数据的序号,或者是否是最后一个分段数据等。) 这种类似的标识信息。

之后接收方在接受固定数据长度的情况下,接收数据然后组合每次接收到数据的位置。最终组成整个数据。如果您发送的数据量不是太大,并且不太要求速率的情况下可能需要考虑每次发送的数据总量要小于路由器的MTU值,这样避免路由器在接收到数据时进行分段重组。这是一种方式。

2.如果是不固定接受的数据长度的话。实现到是可以实现,但是不能应用于大数据量。

这是之前写的一个方法,可以参考一下:)

/// <summary> /// 同步(阻塞)方式接收来自远程发来的数据,此方法会做数据分片合并操作。会一次返回远程发来的数据,无论多大。 /// </summary> /// <returns>接收到的数据</returns> public virtual ReceivedResult Receive() int availableCount = 0; int receiveCount = 0; byte[] data = null; TimeSpan pastSpan = TimeSpan.FromTicks(DateTime.Now.Ticks); while (this.socket.Available < 1) {

//判断是否超出接受超时限定 if ((this.receiveTimeout > 0) && ((TimeSpan.FromTicks(DateTime.Now.Ticks).Subtract(pastSpan).Seconds * 1000) > this.receiveTimeout)) break; Thread.Sleep(10); int cavailable = this.socket.Available; availableCount += cavailable; byte[] cdata = new byte[cavailable]; int creceive = this.socket.Receive(cdata); if (creceive < 1) break; receiveCount += creceive; if (availableCount.Equals(cavailable)) data = cdata; byte[] odata = cdata; data = new byte[availableCount]; if (null != odata) odata.CopyTo(data, 0); cdata.CopyTo(data, odata.Length); while (this.socket.Available > 0); catch (Exception) if (null != this.OnPreReceived) this.OnPreReceived(data); return new ReceivedResult() Data = data State = this.computeReceivedResult(null == data ? 0 : data.Length, receiveCount)