正确收发数据流


主要解决网络收发数据的问题

解决粘包问题的方法

  • 长度信息法,在发送的信息之前附加上长度,比如发送两个字符串“hellounity”和love“”不希望单个被拆开,于是发送信息"10hellounity4love",尽当读取到的字符串的长度与表明的长度一致时,才会整体读取,否则就会等待数据完整到达。
  • 固定长度法,每次都发送固定长度的字符,多余的空间用其他符号填充,如果字符串的长度大于固定长度,则拆分成小的字符,再拼接。
  • 结束符号法,规定一个符号为结束符,那么可以区分不同的字符串。
    实现采用长度信息法

长度信息法的代码

如果是16位的话,2个字节表示长度,如果是32位的话,4个字节表示长度,这里采用16位。
那么修改Send函数,之前的Send函数如下:

public void Send()
	{
		//Send
		string sendStr = InputFeld.text;
		byte[] sendBytes = System.Text.Encoding.Default.GetBytes(sendStr);
		socket.Send(sendBytes);

修改之后的Send函数如下,主要是附加了长度信息

public void Send()
	{
		//Send
		string sendStr = InputFeld.text;
		byte[] bodyBytes = System.Text.Encoding.Default.GetBytes(sendStr);
		Int16 len = (Int16)bodyBytes.Length;
		byte[] lenBytes = BitConverter.GetBytes(len);
		byte[] sendBytes = lenBytes.Concat(bodyBytes).ToArray();
		socket.Send(sendBytes);
	}

比如HelloWorld,修改之后成为0AHelloWorld再转成二进制。

接收的时候需要一个buffCount表示缓存区的以及读入的数据的长度,然后据此判断(16位):

  • buffCount <=2,说明缓存区中还没有数据,不处理。
  • 缓存区数据无法构成完整的消息,不处理,等待下一次接收。
  • 缓存区数据长度大于完整信息长度,取出字符串,并且更新缓冲区,目前采用后面数据直接覆盖前面数据的方法,类似于数组删除一个数据之后,后面的数据都往前移。

代码整合

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net.Sockets;
using UnityEngine.UI;
using System;
using System.Linq;

public class Echo : MonoBehaviour {

	//定义套接字
	Socket socket;
	//UGUI
	public InputField InputFeld;
	public Text text;
	//接收缓冲区
	byte[] readBuff = new byte[1024];
	//接收缓冲区的数据长度
	int buffCount = 0;
	//显示文字
	string recvStr = "";


	//点击连接按钮
	public void Connection()
	{
		//Socket
		socket = new Socket(AddressFamily.InterNetwork,
			SocketType.Stream, ProtocolType.Tcp);
		//为了精简代码:使用同步Connect
		//             不考虑抛出异常
		socket.Connect("127.0.0.1", 8888);

		socket.BeginReceive( readBuff, buffCount, 
							1024-buffCount, 0, ReceiveCallback, socket);
	}

	//Receive回调
	public void ReceiveCallback(IAsyncResult ar){
		try {
			Socket socket = (Socket) ar.AsyncState;
			//获取接收数据长度
			int count = socket.EndReceive(ar);
			buffCount += count;
			//处理二进制消息
			OnReceiveData();
			//继续接收数据
			
			socket.BeginReceive( readBuff, buffCount, 
							1024-buffCount, 0, ReceiveCallback, socket);
		}
		catch (SocketException ex){
			Debug.Log("Socket Receive fail"
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值