在当前的版本中,服务端和客户端的收发报文都是 固定长度的数据 且是在本地网络运行,因此粘包和少包的情况还未出现。
那么dataLength的作用在目前版本中的作用很小。
但当网络收发数据是变长数据的时,例如发送的是图片文件,dataLength的作用是告知收发文件的大小。本节对服务端和客户端的收发逻辑进行简单改进,以使用dataLength提供的长度进行收发。
对服务端的收发逻辑做如下更改:
while (true)
{
//使用一个缓冲区接收数据 暂定最大收发1024个字节 后续会改进大文件的传输
char *szRecv = new char[1024];
//5 首先接收数据包头
int nlen = recv(_clientSock, szRecv, sizeof(DataHeader), 0); //接受客户端的数据 第一个参数应该是客户端的socket对象
if (nlen <= 0)
{
//客户端退出
cout << "客户端已退出,任务结束" << endl;
break;
}
DataHeader* header = (DataHeader*)szRecv;
switch (header->cmd)
{
case CMD_LOGIN:
{
Login* _login;
//读取Header->dataLength的数据长度
recv(_clientSock, szRecv + sizeof(DataHeader),header->dataLength - sizeof(DataHeader),0);
_login = (Login*)szRecv;
cout << "收到命令:CMD_LOGIN" << " 数据长度 = " << header->dataLength<<" UserName = "<< _login->userName<<" Password = "<<_login->Password << endl;
//忽略了判断用户名密码是否正确的过程
LoginResult _loginres;
send(_clientSock, (char*)&_loginres, sizeof(LoginResult), 0);
}break;
case CMD_LOGINOUT:
{
Logout *_logout;
recv(_clientSock, szRecv + sizeof(DataHeader), header->dataLength - sizeof(DataHeader), 0);
cout << "收到命令:CMD_LOGOUT" << " 数据长度 = " << header->dataLength << " UserName = " << _logout->userName<< endl;
LogoutResult _logoutres;
send(_clientSock, (char*)&_logoutres, sizeof(LogoutResult), 0);
}break;
default:
{
header->cmd = CMD_ERROR;
header->dataLength = 0;
send(_clientSock, (char*)&header, sizeof(DataHeader), 0);
}
break;
}
}