// Client.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <string.h>
#include <assert.h>
#include <iostream>
#include <winsock2.h>
#include <process.h>
#pragma comment(lib, "WS2_32.lib")
using namespace std;
#define CLIENT_SETUP_FAIL 1 //启动客户端失败
#define CLIENT_CREATETHREAD_FAIL 2 //创建线程失败
#define CLIENT_CONNECT_FAIL 3 //网络连接断开
#define TIMEFOR_THREAD_EXIT 1000 //子线程退出时间
#define TIMEFOR_THREAD_SLEEP 500 //线程睡眠时间
#define SERVERIP "192.168.1.132" //服务器IP
#define SERVERPORT 5555 //服务器TCP端口
#define MAX_NUM_BUF 48 //缓冲区的最大长度
#define ADD '+' //+
#define SUB '-' //-
#define MUT '*' //*
#define DIV '/' ///
#define EQU '=' //=
//数据包类型
#define EXPRESSION 'E' //算数表达式
#define BYEBYE 'B' //消息byebye
#define HEADERLEN (sizeof(hdr)) //头长度
//数据包头结构该结构在win32xp下为4byte
typedef struct _head
{
char type;//类型
unsigned short len;//数据包的长度(包括头的长度)
}hdr, *phdr;
//数据包中的数据结构
typedef struct _data
{
char buf[MAX_NUM_BUF];
}DATABUF, *pDataBuf;
SOCKET sClient; //套接字
HANDLE hThreadSend; //发送数据线程
HANDLE hThreadRecv; //接收数据线程
DATABUF bufSend; //发送数据缓冲区
DATABUF bufRecv; //接收数据缓冲区
CRITICAL_SECTION csSend; //临界区对象,锁定bufSend
CRITICAL_SECTION csRecv; //临界区对象,锁定bufRecv
BOOL bSendData; //通知发送数据线程
HANDLE hEventShowDataResult; //显示计算结果的事件
BOOL bConnecting; //与服务器的连接状态
HANDLE arrThread[2]; //子线程数组
BOOL InitClient(void); //初始化
BOOL ConnectServer(void); //连接服务器
BOOL CreateSendAndRecvThread(void); //创建发送和接收数据线程
void InputAndOutput(void); //用户输入数据
void ExitClient(void); //退出
void InitMember(void); //初始化全局变量
BOOL InitSockt(void); //创建SOCKET
DWORD __stdcall RecvDataThread(void* pParam); //接收数据线程
DWORD __stdcall SendDataThread(void* pParam); //发送数据线程
BOOL PackByebye(const char* pExpr); //将输入的"Byebye" "byebye"的字符串打包
BOOL PackExpression(const char *pExpr); //将输入的算数表达式打包
void ShowConnectMsg(BOOL bSuc); //显示连接服务器消息
void ShowDataResultMsg(void); //显示连计算结果
void ShowTipMsg(BOOL bFirstInput); //显示提示信息
int main(int argc, char* argv[])
{
//初始化
if (!InitClient())
{
ExitClient();
return CLIENT_SETUP_FAIL;
}
//连接服务器
if (ConnectServer())
{
ShowConnectMsg(TRUE);
}else{
ShowConnectMsg(FALSE);
ExitClient();
return CLIENT_SETUP_FAIL;
}
//创建发送和接收数据线程
if (!CreateSendAndRecvThread())
{
ExitClient();
return CLIENT_CREATETHREAD_FAIL;
}
//用户输入数据和显示结果
InputAndOutput();
//退出
ExitClient();
return 0;
}
/**
* 初始化
*/
BOOL InitClient(void)
{
//初始化全局变量
InitMember();
//创建SOCKET
if (!InitSockt())
{
return FALSE;
}
return TRUE;
}
/**
* 初始化全局变量
*/
void InitMember(void)
{
//初始化临界区
InitializeCriticalSection(&csSend);
InitializeCriticalSection(&csRecv);
sClient = INVALID_SOCKET; //套接字
hThreadRecv = NULL; //接收数据线程句柄
hThreadSend = NULL; //发送数据线程句柄
bConnecting = FALSE; //为连接状态
bSendData = FALSE; //不发送数据状态
//初始化数据缓冲区
memset(bufSend.buf, 0, MAX_NUM_BUF);
memset(bufRecv.buf, 0, MAX_NUM_BUF);
memset(arrThread, 0, 2);
//手动设置事件,初始化为无信号状态
hEventShowDataResult = (HANDLE)CreateEvent(NULL, TRUE, FALSE, NULL);
}
/**
* 创建非阻塞套接字
*/
BOOL InitSockt(void)
{
int reVal; //返回值
WSADATA wsData; //WSADATA变量
reVal = WSAStartup(MAKEWORD(2,2),&wsData);//初始化Windows Sockets Dll
//创建套接字
sClient = socket(AF_INET, SOCK_STREAM, 0);
if(INVALID_SOCKET == sClient)
return FALSE;
//设置套接字非阻塞模式
unsigned long ul = 1;
/* reVal = ioctlsocket(sClient, FIONBIO, (unsigned long*)&ul);
if (reVal == SOCKET_ERROR)
return FALSE;*/
return TRUE;
}
/**
* 客户端退出
*/
void ExitClient(void)
{
DeleteCriticalSection(&csSend);
DeleteCriticalSection(&csRecv);
CloseHandle(hThreadRecv);
CloseHandle(hThreadSend);
closesocket(sClient);
WSACleanup();
return;
}
/**
* 连接服务器
*/
BOOL ConnectServer(void)
{
int reVal; //返回值
sockaddr_in serAddr;//服务器地址
serAddr.sin_family = AF_INET;
// serAddr.sin_port = htons(SERVERPORT);
// serAddr.sin_addr.S_un.S_addr = inet_addr(SERVERIP);
serAddr.sin_port = htons(5555);
serAddr.sin_addr.S_un.S_addr = inet_addr("192.168.1.131");
for (;;)
{
//连接服务器
reVal = connect(sClient, (struct sockaddr*)&serAddr, sizeof(serAddr));
//处理连接错误
if(SOCKET_ERROR == reVal)
{
int nErrCode = WSAGetLastError();
if( WSAEWOULDBLOCK == nErrCode ||//连接还没有完成
WSAEINVAL == nErrCode)
{
continue;
}else if (WSAEISCONN == nErrCode)//连接已经完成
{
break;
}else//其它原因,连接失败
{
return FALSE;
}
}
if ( reVal == 0 )//连接成功
break;
}
bConnecting = TRUE;
return TRUE;
}
/**
* 显示连接服务器失败信息
*/
void ShowConnectMsg(BOOL bSuc)
{
if (bSuc)
{
cout << "******************************" << endl;
cout << "* *" << endl;
cout << "* Succeed to connect server! *" << endl;
cout << "* *" << endl;
cout << "******************************" << endl;
}else{
cout << "***************************" << endl;
cout << "* *" << endl;
cout << "* Fail to connect server! *" << endl;
cout << "* *" << endl;
cout << "***************************" << endl;
}
return;
}
/**
* 表达式结果
*/
void ShowDataResultMsg(void)
{
EnterCriticalSection(&csRecv);
cout << "**********************************" << endl;
cout << "* *" << endl;
cout << "* Result: *" << endl;
cout << bufRecv.buf <<endl;
cout << "* *" << endl;
cout << "**********************************" << endl;
LeaveCriticalSection(&csRecv);
}
/**
* 提示信息
*/
void ShowTipMsg(BOOL bFirstInput)
{
if (bFirstInput)//首次显示
{
cout << "**********************************" << endl;
cout << "* *" << endl;
cout << "* Please input expression. *" << endl;
cout << "* Usage:NumberOperatorNumber= *" << endl;
cout << "* *" << endl;
cout << "**********************************" << endl;
}else{
cout << "**********************************" << endl;
cout << "* *" << endl;
cout << "* Please input: expression *" << endl;
cout << "* Usage:NumberOperatorNumber= *" << endl;
cout << "* *" << endl;
cout << "* If you want to exit. *" << endl;
cout << "* Usage: Byebye or byebye *" << endl;
cout << "* *" << endl;
cout << "**********************************" << endl;
}
}
/**
* 创建发送和接收数据线程
*/
BOOL CreateSendAndRecvThread(void)
{
//创建接收数据的线程
unsigned long ulThreadId;
hThreadRecv = CreateThread(NULL, 0, RecvDataThread, NULL, 0, &ulThreadId);
if (NULL == hThreadRecv)
return FALSE;
//创建发送数据的线程
hThreadSend = CreateThread(NULL, 0, SendDataThread, NULL, 0, &ulThreadId);
if (NULL == hThreadSend)
return FALSE;
//添加到线程数组
arrThread[0] = hThreadRecv;
arrThread[1] = hThreadSend;
return TRUE;
}
/**
* 输入数据和显示结果
*/
void InputAndOutput(void)
{
char cInput[MAX_NUM_BUF]; //用户输入缓冲区
BOOL bF
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
05.rar (44个子文件)
05
5.3
Server
StdAfx.cpp 293B
Desktop_.ini 10B
Debug
Server.pdb 233KB
Client.sbr 0B
vc60.pdb 180KB
Server.bsc 2.21MB
vc60.idb 153KB
Server.pch 199KB
Client.obj 32KB
StdAfx.obj 2KB
Server.sbr 0B
Server.obj 67KB
Server.exe 108KB
StdAfx.sbr 4KB
Server.ilk 103KB
StdAfx.h 769B
Server.dsp 5KB
Server.opt 52KB
Server.plg 1KB
Client.cpp 6KB
Server.ncb 49KB
Server.cpp 11KB
Server.dsw 537B
Client.h 2KB
5.5
Client
Client.dsp 4KB
Client.ncb 49KB
StdAfx.cpp 293B
Desktop_.ini 10B
Client.plg 1KB
Debug
Client.exe 96KB
Client.sbr 0B
vc60.pdb 204KB
Client.pdb 201KB
Client.pch 199KB
Client.bsc 1.88MB
vc60.idb 129KB
Client.ilk 118KB
Client.obj 58KB
StdAfx.obj 2KB
StdAfx.sbr 4KB
StdAfx.h 769B
Client.dsw 537B
Client.cpp 14KB
Client.opt 49KB
共 44 条
- 1
资源评论
- 喔魔2015-01-23资源不错,值得学习
colorsky_010
- 粉丝: 7
- 资源: 17
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功