2021-07-14客户端移植Linux

#define WIN32_LEAN_AND_MEAN

#define _WINSOCK_DEPRECATED_NO_WARNINGS	
#define _CRT_SECURE_NO_WARNINGS				

#ifdef _WIN32
  #include<windows.h>
  #include<WinSock2.h>
#else
  #include<unistd.h>
  #include<arpa/inet.h>
  #include<string.h>

  #define SOCKET int
  #define INVALID_SOCKET (int)(~0)
  #define SOCKET_ERROR (-1)
#endif

#include<stdio.h>
#include<thread>



//指令
enum CMD
{
	CMD_LOGIN,
	CMD_LOGIN_RESULT,
	CMD_LOGINOUT,
	CMD_LOGINOUT_RESULT,
	CMD_NEW_USER_JOIN,
	CMD_ERROR
};
//消息头
struct DataHeader
{
	short dataLength;
	short cmd;
};
//登录
struct Login : public DataHeader
{
	Login()
	{
		dataLength = sizeof(Login);
		cmd = CMD_LOGIN;
	}
	char userName[32];
	char PassWord[32];
};
//登录结果
struct LoginResult : public DataHeader
{
	LoginResult()
	{
		dataLength = sizeof(LoginResult);
		cmd = CMD_LOGIN_RESULT;
		result = 0;
	}
	int result;

};
//登出
struct Loginout : public DataHeader
{
	Loginout()
	{
		dataLength = sizeof(Loginout);
		cmd = CMD_LOGINOUT;
	}
	char userName[32];
};
//登出结果
struct LoginoutResult : public DataHeader
{
	LoginoutResult()
	{
		dataLength = sizeof(LoginoutResult);
		cmd = CMD_LOGINOUT_RESULT;
		result = 0;
	}
	int result;
};

struct NewUserJoin : public DataHeader
{
	NewUserJoin()
	{
		dataLength = sizeof(NewUserJoin);
		cmd = CMD_NEW_USER_JOIN;
		sock = 0;
	}
	int sock;
};

//处理请求函数
int processor(SOCKET _cSock)
{
	char szRecv[1024] = { };
	int nLen = recv(_cSock, szRecv, sizeof(DataHeader), 0);
	// 5 接收客户端数据
	//将数据放在缓冲区中,缓冲区大小为1024
	//首先判断消息头
	DataHeader* header = (DataHeader*)szRecv;
	if (nLen <= 0)
	{
		printf("与服务器断开连接,任务结束。\n");
		return -1;
	}
	// 6 处理请求
	switch (header->cmd)
	{
		case CMD_LOGIN_RESULT:
		{
			recv(_cSock, szRecv + sizeof(DataHeader), header->dataLength - sizeof(DataHeader), 0);
			LoginResult* loginRet = (LoginResult*)szRecv;
			printf("收到服务端消息:CMD_LOGIN_Result,数据长度 : %d\n", loginRet->dataLength);
		}
		break;
		case CMD_LOGINOUT_RESULT:
		{
			recv(_cSock, szRecv + sizeof(DataHeader), header->dataLength - sizeof(DataHeader), 0);
			LoginoutResult* loginout = (LoginoutResult*)szRecv;
			printf("收到服务端消息:CMD_LOGINOUT_Result,数据长度 : %d\n", loginout->dataLength);
		}
		break;
		case CMD_NEW_USER_JOIN:
		{
			recv(_cSock, szRecv + sizeof(DataHeader), header->dataLength - sizeof(DataHeader), 0);
			NewUserJoin* userJoin = (NewUserJoin*)szRecv;
			printf("收到服务端消息:CMD_NEW_USER_JOIN,数据长度 : %d\n",  userJoin->dataLength);
		}
		break;

	}
}
bool g_bRun = true;
void  cmdThread(SOCKET _sock)
{
	while (true)
	{
		char cmdBuf[256] = { };
		scanf("%s", cmdBuf);
		if (0 == strcmp(cmdBuf, "exit"))
		{
			printf("退出cmdThread线程\n");
			g_bRun = false;
			break;
		}
		else if (0 == strcmp(cmdBuf, "login"))
		{
			Login login;
			strcpy(login.userName, "yql");
			strcpy(login.PassWord, "yqlyyds");
			send(_sock, (const char*)&login, sizeof(login), 0);
		}
		else if (0 == strcmp(cmdBuf, "loginout"))
		{
			Loginout loginout;
			strcpy(loginout.userName, "yql");
			send(_sock, (const char*)&loginout, sizeof(loginout), 0);
		}
		else {
			printf("不支持的命令,请重新输入。\n");
		}
	}
}

int main()
{
#ifdef _WIN32
	WORD ver = MAKEWORD(2, 2);				//创建WINDOWS版本号
	WSADATA dat;
	WSAStartup(ver, &dat);					//启动网络环境,此函数调用了一个WINDOWS的静态链接库,因此需要加入静态链接库文件
#endif	
	//-----------------

	//-- 用socket API建立简易TCP客户端
	// 1 建立一个socket
	SOCKET _sock = socket(AF_INET, SOCK_STREAM, 0);
	if (INVALID_SOCKET == _sock)
	{
		printf("错误,建立Socket失败...\n");
	}
	else {
		printf("建立Socket成功...\n");
	}
	// 2 连接服务器 connect 
	sockaddr_in _sin = { };
	_sin.sin_family = AF_INET;
	_sin.sin_port = htons(4567);
#ifdef _WIN32
	_sin.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
#else
	_sin.sin_addr.s_addr = inet_addr("192.168.43.1");
#endif
	int ret = connect(_sock, (sockaddr*)&_sin, sizeof(sockaddr_in));
	if (ret == SOCKET_ERROR)
	{
		printf("错误,连接失败...\n");
	}
	else {
		printf("连接成功...\n");
	}
	//启动线程
	std::thread t1(cmdThread, _sock);
	//分离主线程和子线程
	t1.detach();
	while (g_bRun)
	{
		fd_set fdRead;
		fd_set fdWrite;
		fd_set fdExc;
		//清空
		FD_ZERO(&fdRead);
		FD_ZERO(&fdWrite);
		FD_ZERO(&fdExc);
		//将描述符存入数组
		FD_SET(_sock, &fdRead);
		FD_SET(_sock, &fdWrite);
		FD_SET(_sock, &fdExc);

		timeval t = { 1,0 };
		int ret = select(_sock, &fdRead, 0, 0, &t);
		if (ret < 0)
		{
			printf("select任务结束1\n");
			break;
		}
		if (FD_ISSET(_sock, &fdRead))
		{
			FD_CLR(_sock, &fdRead);

			if (-1 == processor(_sock))
			{
				printf("select任务结束2\n");
				break;
			}
		}

		//printf("空闲时间处理其他业务...\n");

	}

	// 7 关闭套接字 closesocket
#ifdef _WIN32
	closesocket(_sock);
	//-----------------
	//清除Windows socket环境

	WSACleanup();							//关闭Socket网络环境
#else
	close(_sock);
#endif
	printf("已退出,任务结束...\n");
	getchar();
	return 0;

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值