//网络数据报文的格式定义
///报文有两个部分 ,包头和包体,是网络消息的基本单元
///包头:描述本次消息包的大小,描述数据的作用
///包体:数据
enum CMD
{
CMD_LOGIN,
CMD_LOGRESULT,
CMD_LOGOUT,
CMD_LOGOUTRESULT,
CMD_ERROR
};
struct DataHeader
{
short DataLength;//数据长度;
short sCmd; //命令作用;
};
struct Login
{
//数据包体.
char UserName[32];
char PassName[32];
};
struct LoginResult
{
//返回的结果;
int result;
};
struct LogOut
{
char UserName[32];
};
struct LogOutResult
{
//返回的结果;
int result;
};
int main()
{
WORD ver = MAKEWORD(2, 2);
WSADATA wsadata;
WSAStartup(ver, &wsadata);
//----------------socket 创建套接字
SOCKET Sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == Sock)
{
printf("创建套接字 失败\r\n");
}
//----------------socket 绑定;
sockaddr_in addr = {};
addr.sin_family = AF_INET;
addr.sin_port = htons(8888);
addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
if (SOCKET_ERROR == bind(Sock, (sockaddr *)&addr, sizeof(sockaddr)))
{
printf("Error , 绑定网络端口失败... \r\n");
}
else
{
printf("绑定网络端口成功... \r\n");
}
// 3 --------------- listen
if (SOCKET_ERROR == listen(Sock, 5))
{
printf("Error , 监听网络端口失败... \r\n");
}
else
{
printf("监听网络端口成功... \r\n");
}
// 4 ------------- 等待客户端连接 单用户 多用户要引用多线程 处理....
sockaddr_in ClientInfo = {};
int ClientSock = INVALID_SOCKET;
int listenLen = sizeof(sockaddr);
char rep[] = { "hello I‘m Server" };
ClientSock = accept(Sock, (sockaddr *)&ClientInfo, &listenLen);
if (INVALID_SOCKET == ClientSock)
{
printf(" 客户端连接的套接字有误\r\n");
}
else
{
printf("ClientSock = %d , ClinetIp = %s ,ClientPort = %d\r\n", ClientSock, inet_ntoa(ClientInfo.sin_addr), ntohs(ClientInfo.sin_port));
//send(ClientSock, rep, strlen(rep) + 1, 0);
}
char sendError[] = { "错误的请求" };
while (true)
{
DataHeader Header = {};
//5 接收客户端的请求数据
int nlen = recv(ClientSock, (char *)&Header, sizeof(DataHeader), 0);
if (nlen <= 0)
{
printf("客户端已退出,任务结束\r\n");
break;
}
printf("收到的命令 : CMD %d DataLength = %d\r\n", Header.sCmd, Header.DataLength);;
//6 处理请求;
switch (Header.sCmd)
{
case CMD_LOGIN:
{
//7.接收客户端 数据 并返回结果;
Login Log = {};
recv(ClientSock, (char *)&Log, sizeof(Login), 0);
//忽略判断用户密码是否正确的过程;
DataHeader hd = { sizeof(LoginResult), CMD_LOGRESULT };
send(ClientSock, (char *)&hd, sizeof(DataHeader), 0);
LoginResult ret = { 1 };
send(ClientSock, (char *)&ret, sizeof(LoginResult), 0);
}
break;
case CMD_LOGOUT:
{
//7.接收客户端 数据 并返回结果;
LogOut logout= {};
recv(ClientSock, (char *)&logout, sizeof(LogOut), 0);
//忽略判断用户密码是否正确的过程;
DataHeader hd = { sizeof(LogOutResult), CMD_LOGOUTRESULT };
send(ClientSock, (char *)&hd, sizeof(DataHeader), 0);
LogOutResult ret = { 1 };
send(ClientSock, (char *)&ret, sizeof(LogOutResult), 0);
}
break;
default:
{
char Error[128] = {};
recv(ClientSock, (char *)&Error, 128, 0);
printf("客户端Error数据请求: %s\r\n", Error);
DataHeader hd = { 128, CMD_ERROR };
send(ClientSock, (char *)&hd, sizeof(DataHeader), 0);
char ErrorRet[] = {"请求的数据命令错误"};
send(ClientSock, (char *)&ErrorRet,strlen(ErrorRet)+1, 0);
}
break;
}
}
// 8 关闭Socket //套接字 ;
closesocket(Sock);
WSACleanup();
return 0;
}