记事本做网站怎么加图片,做网站后台,网络营销哪些公司好做呢,广平手机网站建设要构建网络版象棋#xff0c;首先应该创建服务器与客户端#xff0c;建立socket连接
1) 开局#xff0c;你是什么颜色 2#xff09;选择棋子#xff0c; 3#xff09;走棋 4#xff09;悔棋#xff08;悔棋悔两步#xff09; 5#xff09;认输
网络实现#x…要构建网络版象棋首先应该创建服务器与客户端建立socket连接
1) 开局你是什么颜色 2选择棋子 3走棋 4悔棋悔棋悔两步 5认输
网络实现 1建立连接 a.主机建立监听socket b.accept c.关闭监听socket
a.客户端连接服务器
2发送报文 1服务器给客户端发送开局报文
2选棋 发送选棋报文 3走棋 发送走棋报文
4悔棋 5认输 重新开始
报文格式定义
第一个字节表示命令字 0表示开具1表示选其2表示走棋3表示悔棋4表示认输
开局报文 [0][0或者1] 收到0表示走黑棋收到1表示走红旗 [0][0] [0][1] 选棋报文 [1][0~31] 走棋报文 [2][0~31][x][y] x和y已经转换好的 悔棋 [3] 认输 [4][0或者1]
运行时设计 定义一个全局变量 char packet[4]用来保存报文 定义一个定时器每秒去收socket #ifndef _Net_H__#define _Net_H__#ifdef WIN32#include WinSock2.h#else//linux and android#endif // WIN32class Net{public:static SOCKET _server;static SOCKET _connet;static int _isConnected;static int _isRecvComplete;static char* _recvData;static bool Listen(short port9999);static bool isConnected();static bool Connect(const char*ip,short port9999);static int Send(const char*buffer,int len);//接收数据的接口static bool RecvStart();static bool isRecvComplete();static char *RecvData(int len);static DWORD WINAPI AcceptThreadFunc(void *arg);static DWORD WINAPI RecvThreadFunc(void *arg);};#endif
首先服务器需要listen函数一直监听以得到与客户端的连接 bool Net::Listen(short port){SOCKET socksocket(AF_INET,SOCK_STREAM,0);if (sockINVALID_SOCKET){return false;}struct sockaddr_in addr;addr.sin_familyAF_INET;addr.sin_porthtons(port);addr.sin_addr.S_un.S_addrINADDR_ANY;int retbind(sock,(struct sockaddr*)addr,sizeof(addr));if (ret ! 0){closesocket(sock);return false;}listen(sock,10); //10 means listen count//create a therad to accept socket_server sock;_isConnected 0;HANDLE hThread CreateThread(NULL, 0, AcceptThreadFunc, NULL, 0, NULL);CloseHandle(hThread);return true;}DWORD Net::AcceptThreadFunc(void *arg){_connet accept(_server, NULL, NULL);_isConnected 1;return 0;}
客户端则需要connect函数与服务器建立连接 bool Net::Connect(const char*ip,short port){_connetsocket(AF_INET,SOCK_STREAM,0);if (_connetINVALID_SOCKET){return false;}struct sockaddr_in addr;addr.sin_family AF_INET;addr.sin_port htons(port);addr.sin_addr.S_un.S_addr inet_addr(ip);int ret connect(_connet, (struct sockaddr*)addr, sizeof(addr));if (ret ! 0){closesocket(_connet);return false;}return true;}
如果建立连接成功则可以互相传递数据了此时服务器可以关闭连接监听 void SceneGame::startServer(CCObject*){_bredSidetrue;Net::Listen();schedule(schedule_selector(SceneGame::CheckListen));}void SceneGame::CheckListen(float){if (Net::isConnected()){unschedule(schedule_selector(SceneGame::CheckListen));//game start and do some initiate gameCCLog(server start game\n);}}
服务器与客户端互相发送数据需要send函数 int Net::Send(const char*buffer,int len){return send(_connet,buffer,len,0);}
接收数据需要receve函数保持监听 bool Net::RecvStart(){_isRecvComplete0;HANDLE hThreadCreateThread(NULL,0,RecvThreadFunc,NULL,0,NULL);CloseHandle(hThread);return true;}bool Net::isRecvComplete(){return _isRecvComplete;}char *Net::RecvData(int len){len0;_isRecvComplete0;return _recvData;}DWORD Net::RecvThreadFunc(void *arg){static char buf[16];recv(_connet,buf,1,0);if (buf[0]1){recv(_connet,buf[1],1,0);}else if(buf[0]2){for (int i1;i3;i){recv(_connet,buf[i],1,0);}}//stop receve_recvDatabuf;_isRecvComplete1;return 0;}
在象棋中调用发送数据发送完毕之后轮到对方走了此时要打开接收数据监听 //send stepStep* step *_steps.rbegin();char buf[4];buf[0] 2;buf[1] step-moveid;buf[2] step-rowTo;buf[3] step-colTo;Net::Send(buf, 4);//receive messageNet::RecvStart();schedule(schedule_selector(SceneGame::CheckRecv));
接收到数据之后要关闭接收监听然后开始发送数据象棋根据传递的报文判断对方的信息分别以123开头表示选择走棋其中1与3还需要继续接收数据2可以关闭数据接收。 void SceneGame::CheckRecv(float){if (Net::isRecvComplete()){unschedule(schedule_selector(SceneGame::CheckRecv));int len;char *dataNet::RecvData(len);//accord to the data protocoal do some workif (data[0]1){//selected _selectiddata[1];_selectSprite-setPosition(_s[_selectid]-fromPlate());_selectSprite-setVisible(true);//continue receiveNet::RecvStart();schedule(schedule_selector(SceneGame::CheckRecv));}else if(data[0]2){//move stoneStone* s _s[data[1]];int row 9 - data[2];int col 8 - data[3];int killid getStoneFromRowCol(row, col);recordStep(_selectid, killid, _s[_selectid]-_row, _s[_selectid]-_col, row, col);// 移动棋子s-_row row;s-_col col;s-setPosition(s-fromPlate());if (killid ! -1){Stone* ks _s[killid];ks-_dead true;ks-setVisible(false);}_selectid -1;_selectSprite-setVisible(false);_bRedTurn !_bRedTurn;}else if(data[0]3){doRegret2();//continue receiveNet::RecvStart();schedule(schedule_selector(SceneGame::CheckRecv));}}}