继续修改前边的代码,网络报文数据格式自定义
server
#define WIN32_LEAN_AND_MEAN
#include <WinSock2.h>
#include <windows.h>
#include <WS2tcpip.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib")
struct DataProgram
{
int age;
char name[36];
};
enum CMD
{
CMD_LOGIN = 1,
CMD_LOGOUT,
CMD_ERROR
};
struct DataHeader
{
short cmd;
short dataLength;
};
struct Login
{
char username[32];
char passwd[32];
};
struct LoginResult
{
short result;
};
struct Logout
{
char username[32];
};
struct LogoutResult
{
short result;
};
int main()
{
WORD ver = MAKEWORD(2, 2);
WSADATA dat;
WSAStartup(ver,&dat);
//SOCK_DGRAM IPPROTO_UDP
SOCKET _sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (_sock == INVALID_SOCKET)
{
printf("socket create failed\n");
}
else
{
printf("socket create sucess\n");
sockaddr_in _sin = {};
_sin.sin_family = AF_INET;
_sin.sin_addr.S_un.S_addr = INADDR_ANY;//inet_addr("127.0.0.1")
//_sin.sin_addr.s_addr = htonl(INADDR_ANY);
_sin.sin_port = htons(4567);
int bindresult = bind(_sock, (sockaddr *)&_sin, sizeof(_sin));
if (bindresult == SOCKET_ERROR)
{
printf("socket bind Failed\n");
}
else
{
printf("socket bind sucess\n");
int listenresult = listen(_sock, 5);
if (listenresult == SOCKET_ERROR)
{
printf("socket listen failed\n");
}
else
{
printf("socket listen sucess\n");
sockaddr_in clientAddr = {};
int nAddrLen = sizeof(clientAddr);
SOCKET _csock = INVALID_SOCKET;
_csock = accept(_sock, (sockaddr *)&clientAddr, &nAddrLen);
if (_csock == INVALID_SOCKET)
{
printf("Error,接受到无效客户端socket....\n");
}
char str[INET_ADDRSTRLEN];
printf("new client:%s-%d-%d\n", inet_ntop(AF_INET, &clientAddr.sin_addr, str, sizeof(str)),
clientAddr.sin_port,
clientAddr.sin_family);
//inet_ntoa(clientAddr.sin_addr)
while (true)
{
DataHeader header = {};
int len = recv(_csock, (char *)&header, sizeof(header), 0);
if (len > 0)
{
printf("cmd=%d datalen=%d\n", header.cmd, header.dataLength);
switch (header.cmd)
{
case CMD_LOGIN:
{
Login login = {};
recv(_csock, (char *)&login, sizeof(login), 0);
printf("login name=%s,passwd=%s\n", login.username, login.passwd);
send(_csock, (const char *)&header, sizeof(DataHeader), 0);
LoginResult loginresult = { 1 };
send(_csock, (const char *)&loginresult, sizeof(LoginResult), 0);
break;
}
case CMD_LOGOUT:
{
Logout logout = {};
recv(_csock, (char *)&logout, sizeof(logout), 0);
printf("logout name=%s\n", logout.username);
send(_csock, (const char *)&header, sizeof(header), 0);
LogoutResult logoutresult = { 1 };
send(_csock, (const char *)&logoutresult, sizeof(LogoutResult), 0);
break;
}
default:
{
header.cmd = CMD_ERROR;
header.dataLength = 0;
printf("cmd error\n");
send(_csock, (const char *)&header, sizeof(header), 0);
break;
}
}
}
else
{
closesocket(_csock);
break;
}
}
}
}
}
closesocket(_sock);
WSACleanup();
getchar();
return 0;
}
client
#define WIN32_LEAN_AND_MEAN
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <WinSock2.h>
#include <windows.h>
#include <WS2tcpip.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib")
struct DataProgram
{
int age;
char name[36];
};
enum CMD
{
CMD_LOGIN = 1,
CMD_LOGOUT,
CMD_ERROR
};
struct DataHeader
{
short cmd;
short dataLength;
};
struct Login
{
char username[32];
char passwd[32];
};
struct LoginResult
{
short result;
};
struct Logout
{
char username[32];
};
struct LogoutResult
{
short result;
};
int main()
{
WORD ver = MAKEWORD(2, 2);
WSADATA dat;
WSAStartup(ver, &dat);
SOCKET _sock = socket(AF_INET, SOCK_STREAM, 0);
if (_sock == INVALID_SOCKET)
{
printf("socket create Failed");
}
else
{
sockaddr_in _sin = {};
_sin.sin_family = AF_INET;
_sin.sin_port = htons(4567);
_sin.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
int conresult = connect(_sock, (sockaddr*)&_sin, sizeof(_sin));
if (conresult == SOCKET_ERROR)
{
printf("socket connect Failed");
}
else
{
while (true)
{
char cmdbuf[128] = {};
scanf_s("%s", cmdbuf,128);
if (strcmp(cmdbuf, "login") == 0)
{
Login login = { "sandy","123456" };
DataHeader header = {};
header.cmd = CMD_LOGIN;
header.dataLength = sizeof(login);
send(_sock, (const char *)&header, sizeof(DataHeader), 0);
send(_sock, (const char *)&login, sizeof(Login), 0);
}
else if (strcmp(cmdbuf, "logout") == 0)
{
Logout logout = { "sandy" };
DataHeader header = { CMD_LOGOUT ,sizeof(logout)};
send(_sock, (const char *)&header, sizeof(DataHeader), 0);
send(_sock, (const char *)&logout, sizeof(Logout), 0);
}
else if (strcmp(cmdbuf, "error") == 0)
{
DataHeader header = { CMD_ERROR ,0 };
send(_sock, (const char *)&header, sizeof(DataHeader), 0);
}
DataHeader header = {};
int nlen = recv(_sock, (char *)&header, sizeof(DataHeader), 0);
printf("cmd=%d datalen=%d\n", header.cmd, header.dataLength);
if (nlen > 0)
{
switch (header.cmd)
{
case CMD_LOGIN:
{
LoginResult loginresult = {};
recv(_sock, (char *)&loginresult, sizeof(LoginResult), 0);
printf("loginresult=%d\n", loginresult.result);
break;
}
case CMD_LOGOUT:
{
LogoutResult logoutResult = {};
recv(_sock, (char *)&logoutResult, sizeof(LogoutResult), 0);
printf("logoutresult=%d\n", logoutResult.result);
break;
}
case CMD_ERROR:
{
printf("cmd error\n");
break;
}
}
}
}
}
}
closesocket(_sock);
WSACleanup();
getchar();
return 0;
}
服务器端 加入收包缓冲区逻辑 为后边的解决粘包问题 做基础 对应的客户端跟上边一样 不做任何改动
#define WIN32_LEAN_AND_MEAN
#include <WinSock2.h>
#include <windows.h>
#include <WS2tcpip.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib")
struct DataProgram
{
int age;
char name[36];
};
enum CMD
{
CMD_LOGIN = 1,
CMD_LOGIN_RESULT,
CMD_LOGOUT,
CMD_LOGOUT_RESULT,
CMD_ERROR
};
struct DataHeader
{
short cmd;
short dataLength;
};
struct Login : public DataHeader
{
Login()
{
cmd = CMD_LOGIN;
dataLength = sizeof(Login);
}
char username[32];
char passwd[32];
};
struct LoginResult : public DataHeader
{
LoginResult()
{
cmd = CMD_LOGIN_RESULT;
dataLength = sizeof(LoginResult);
}
short result;
};
struct Logout : public DataHeader
{
Logout()
{
cmd = CMD_LOGOUT;
dataLength = sizeof(Logout);
}
char username[32];
};
struct LogoutResult:public DataHeader
{
LogoutResult()
{
cmd = CMD_LOGOUT_RESULT;
dataLength = sizeof(LogoutResult);
}
short result;
};
int main()
{
WORD ver = MAKEWORD(2, 2);
WSADATA dat;
WSAStartup(ver,&dat);
//SOCK_DGRAM IPPROTO_UDP
SOCKET _sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (_sock == INVALID_SOCKET)
{
printf("socket create failed\n");
}
else
{
printf("socket create sucess\n");
sockaddr_in _sin = {};
_sin.sin_family = AF_INET;
_sin.sin_addr.S_un.S_addr = INADDR_ANY;//inet_addr("127.0.0.1")
//_sin.sin_addr.s_addr = htonl(INADDR_ANY);
_sin.sin_port = htons(4567);
int bindresult = bind(_sock, (sockaddr *)&_sin, sizeof(_sin));
if (bindresult == SOCKET_ERROR)
{
printf("socket bind Failed\n");
}
else
{
printf("socket bind sucess\n");
int listenresult = listen(_sock, 5);
if (listenresult == SOCKET_ERROR)
{
printf("socket listen failed\n");
}
else
{
printf("socket listen sucess\n");
sockaddr_in clientAddr = {};
int nAddrLen = sizeof(clientAddr);
SOCKET _csock = INVALID_SOCKET;
_csock = accept(_sock, (sockaddr *)&clientAddr, &nAddrLen);
if (_csock == INVALID_SOCKET)
{
printf("Error,接受到无效客户端socket....\n");
}
char str[INET_ADDRSTRLEN];
printf("new client:%s-%d-%d\n", inet_ntop(AF_INET, &clientAddr.sin_addr, str, sizeof(str)),
clientAddr.sin_port,
clientAddr.sin_family);
//inet_ntoa(clientAddr.sin_addr)
while (true)
{
char szRecv[1024] = {}; //缓冲区
int len = recv(_csock, szRecv, sizeof(DataHeader), 0);
DataHeader * header = (DataHeader*)szRecv;
if (len >= header->dataLength)
{
}
if (len > 0)
{
printf("cmd=%d datalen=%d\n", header->cmd, header->dataLength);
switch (header->cmd)
{
case CMD_LOGIN:
{
recv(_csock, szRecv + sizeof(DataHeader), header->dataLength - sizeof(DataHeader), 0);
Login *login = (Login *)szRecv;
printf("login name=%s,passwd=%s\n", login->username, login->passwd);
LoginResult loginresult = {};
loginresult.result = 1;
send(_csock, (const char *)&loginresult, sizeof(LoginResult), 0);
break;
}
case CMD_LOGOUT:
{
recv(_csock, szRecv + sizeof(DataHeader), header->dataLength - sizeof(DataHeader), 0);
Logout *logout = (Logout *)szRecv;
printf("logout name=%s\n", logout->username);
LogoutResult logoutresult = {};
logoutresult.result = 1;
send(_csock, (const char *)&logoutresult, sizeof(LogoutResult), 0);
break;
}
default:
{
header->cmd = CMD_ERROR;
header->dataLength = 0;
printf("cmd error\n");
send(_csock, (const char *)&header, sizeof(header), 0);
break;
}
}
}
else
{
closesocket(_csock);
break;
}
}
}
}
}
closesocket(_sock);
WSACleanup();
getchar();
return 0;
}
非常不错的服务器编程教程