利用网络报文传输数据
新增内容
- 新增包头:描述本次传输数据的大小和作用。
- 服务器和客户端新增对登陆登出的状态描述
网络报文定义
报文包括两个部分,是网络传输的基本消息单元
- 包头:描述本次数据包的大小和作用
- 包体:传输的数据
新增后的代码v1.0
服务器整体代码
#define WIN32_LEAN_AND_MEAN
#define SOCKET int //VS2015已经定义好的,可以直接用
#include<WinSock2>
#include<windows.h>
#include<iostream>
#include<string.h>
using namespace std::cout;
//新增
enum CMD //里面包含cmd常见的命令
{
CMD_LOGIN;
CMD_LOGOUT;
CMD_GETINFO;
};
struct DataHeader
{
int dataLength;//描述数据长度
int cmd;//描述数据包的作用
};
struct Login
{
char username[32];
char password[32];
};
struct LoginResult
{
int res;
};
struct LogoutResult
{
int res;
};
struct Logout
{
char username[32];
};
struct DataPackage //以最简单的情形为例,可以依据实际工程需求做自定义定制。
{
int age;
char name[32];
};
//*************************************
int main()
{
WORD ver = MAKEWORD(2,2);//调用API2代创建2.x版本
WSADATA dat;
WSAStartup(ver,&dat);//启动
//创建套接字
SOCKET seradd =socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
//bind
SOCKADDR_IN _sin = {
};
_sin .sin_family = AF_INET;
//sin_port和sin_addr都必须是网络字节序(NBO),一般可视化的数字都是主机字节序。所以需要转换host to net unsigned.数字可改
_sin .sin_port = htons(1234);
_sin.sin_addr_s_un.S_addr = INADDR_ANY;//访问本机任何网络地址都可以,具体也可以改为本机的某个特定地址
if (SOCKET_ERROR == bind(seradd , (sockaddr *) &_sin , sizeof(_sin)))
{
std::cout<<"绑定失败"<<endl;
}
//监听
if (SOCKET_ERROR == listen(seradd,5))
{
std::cout<<"绑定失败"<<endl;
}
//接受
sockaddr_in clentAddr = {
};//不用赋值了,因为是监听到的,不是给定的
int nAddrLen = sizeof(sockaddr_in);//给定长度
SOCKET _cSock = INVAID_SOCKET;
//发送内容需要预先说定
char msgbuf[] = "XXXXXXX";
_cSock = accept(seradd,(sockaddr *) &clentAddr,nAddrLen);
if(_cSock = INVAID_SOCKET)
{
std::cout<<"获取失败"<<endl;
}
char _recvBuf[128] = {
};
while(true)
{
//修正,先接受包头
DataHeader header = {
};
int nLen = recv(_cSock,(char *) &header,sizeof(DataHeader),0);
if(nLen <= 0)
{
cout<<"客户端已经退出,任务结束"<<endl;