在内网中验证,测试粘包原因

  • 在内网终验证,测试粘包原因
    因为我们的数据长度很短,所以不会出现什么问题,

在这里插入图片描述

  • 我们把数据量加大,然后改为持续发送
  • client和server MessageHeader.hpp 修改一下
struct LoginResult : public DataHeader
{
	LoginResult()
	{
		dataLength = sizeof(Login);
		cmd = CMD_LOGIN_RESULT;
		result = 0;	// 0表示正常
	}
	int result;
	char data[1024]; // 多添加一些数据
};
 
  • client 在while里面不停的发送数据

int main()
{
	EasyTcpClient client;
	client.Connect("127.0.0.1", 8888);

	// 启动线程
	std::thread t1(cmdThread, &client); // 这里是用来客户端输入命令的完全跟网络通信没有关系
	t1.detach();

	Login login;
	strcpy(login.UserName, "hhhh");
	strcpy(login.PassWord, "hhhhmmm");

	while (client.isRun())
	{
		client.OnRun();
		client.SendData(&login);
	}

	client.Close();

	printf("已退出\n");
	getchar();
	return 0;
}

  • 为了跟好的看到接收数据的长度,接收数据也稍微修改一下
	int RecvData(SOCKET _sock)
	{
		char szRecv[1024] = {};
		int nLen = (int)recv(_sock, szRecv, sizeof(DataHeader), 0);
		printf("nLen=%d\n", nLen);

		if (nLen <= 0)
		{
			printf("与服务器断开链接....\n");
			return -1;
		}
		/*
		DataHeader* header = (DataHeader*)szRecv;
		recv(_sock, szRecv + sizeof(DataHeader), header->dataLength - sizeof(DataHeader), 0);
		OnNetMsg(header);
		return 0;
		*/
	}
  • server 也稍微修改一下
	int RecvData(SOCKET _cSock)
	{
		char szRecv[1024] = {};
		int nLen = (int)recv(_cSock, szRecv, sizeof(DataHeader), 0);
		printf("nLen=%d\n", nLen);
		if (nLen <= 0)
		{
			printf("client exit...:%d\n", _cSock);
			return -1;
		}

		LoginResult ret;
		SendData(_cSock, &ret);

		/*
		DataHeader* header = (DataHeader*)szRecv;
		recv(_cSock, szRecv + sizeof(DataHeader), header->dataLength - sizeof(DataHeader), 0);
		OnNetMsg(_cSock, header);
		*/
		return 0;
	}

  • 在运行的时候就发现运行了一会之后就卡着不动了
    在这里插入图片描述

这是因为我们发送数据都会优先把数据发送底层的缓冲区里面,
从发送端的发送缓冲区,发送的接收端的接收缓冲区,但是我们每次recv 的数据都是一个DataHeader,
int nLen = (int)recv(_cSock, szRecv, sizeof(DataHeader), 0);
并不是一次性接收的,而且缓冲区里面并不是只有一条数据,而是有多条。
假如我们发送的数据过快,(接收的速度比发送的速度还要慢),这样就会出现溢出的情况,发送端也将会无法发送数据这样就会造成网络阻塞,
我们尽可能的一次性取出缓冲区里面的数据,放在我们代码里面的缓冲区里面,自己定义的一个临时缓冲区
我们建立一个缓冲区,足够大(足够大的意思是根据我们网络传输来定的)

  • 修改
int RecvData(SOCKET _sock)
	{
		// 定义一个足够大的缓冲区
		char szRecv[102400] = {};
		int nLen = (int)recv(_sock, szRecv, 102400, 0);
		....
		....
		return 0;
	}

在这里插入图片描述

这样就可以看到一直在正常的收发,但是这样并不是好的解决方法

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值