📄 server.cpp
字号:
#include "server.h"Master::Master(){}//专门接收数据的函数void Master :: Receiver(){ struct sockaddr_in servaddr,cliaddr; int sockfd,recvnum; socklen_t clilen; char bufrecv[BUF_LEN]; clilen=sizeof(struct sockaddr); char port[5]; //准备连接 sockfd=socket(AF_INET,SOCK_DGRAM,0); if(sockfd==-1) { perror("socket"); //exit(); } bzero(&servaddr,sizeof(servaddr)); bzero(&cliaddr,sizeof(cliaddr)); servaddr.sin_family=AF_INET; servaddr.sin_addr.s_addr=htonl(INADDR_ANY); servaddr.sin_port=htons(1500); if(bind(sockfd,(struct sockaddr*)&servaddr,sizeof(struct sockaddr))==-1) { perror("bind"); //exit(); } mSockFD=sockfd; //接收数据 for(;;) { printf("waiting for datagram...\n"); recvnum=recvfrom(sockfd,bufrecv,BUF_LEN,0,(struct sockaddr *)&mCliaddr,&clilen); if(recvnum==-1) { perror("recvmsg"); //exit(); } strncpy(mRevBuf,bufrecv,recvnum); printf("mRecvBuf:%s",mRevBuf); printf("\nunPacker ::%d\n",mPackDisposer.MsgUnPacker(mMsgRecvd,mRevBuf)); printf("%s\n%s\n%s\n",mMsgRecvd.mID.ascii(), mMsgRecvd.mRequest.ascii(), mMsgRecvd.mContent.ascii()); sprintf(port,"%d",ntohs(cliaddr.sin_port)); printf("port:%s\n",port); sleep(1); //每接收到一个包调Disposer()来处理; printf("Disposer:%d\n",Disposer()); } }//分发器int Master::Disposer(){ if(!mMsgRecvd.mRequest.compare(QString("login"))) HandleLogin(); if(!mMsgRecvd.mRequest.compare(QString("quit"))) HandleQuit(); if(!mMsgRecvd.mRequest.compare(QString("changeseat"))) HandleChangeseat(); return 123;}//Sender将msg打包(格式化)后发送到dstaddrint Master::Sender(Message msg, struct sockaddr_in dstaddr){ int sockfd=socket(AF_INET,SOCK_DGRAM,0); mPackDisposer.MsgPacker(msg,mSndBuf); int sendnum; sendnum =sendto(sockfd,mSndBuf,BUF_LEN,0,(struct sockaddr *)&dstaddr,sizeof(struct sockaddr)); if(sendnum<0) { perror("sendto"); } printf("send, %s to %s, %d\n",mSndBuf,inet_ntoa(dstaddr.sin_addr),ntohs(dstaddr.sin_port)); return 0; }//让所有客户更新大厅int Master::UpdateHall(){ int i,k,templen; char p[BUF_LEN]; Message msg; struct sockaddr_in dstaddr; //找到在线客户,逐个发送更新信息 算法代改进 for(i=2;i<MAX_PLAYER;i++) { if(mPlayerTable[i].mPlayerID.compare(QString("-1"))==0) continue; for(k=2;k<MAX_PLAYER;k++) { if(mPlayerTable[k].mPlayerID.compare(QString("-1"))==0) continue; templen=mPackDisposer.TablePacker(mPlayerTable[k],p); p[templen]='\0'; msg.mID=mPlayerTable[i].mPlayerID; msg.mRequest=QString("update"); msg.mContent=QString(p); //Sender将msg格式化后发送 睡一下,怕客户端丢包,待改进 ConvertQStrToSockaddr(mPlayerTable[i].mAddr, mPlayerTable[i].mPort, dstaddr); Sender(msg, dstaddr); sleep(0.5); } //发送更新结束信息,ID 和Content可以没有,客户端是根据Request来行为 msg.mID=mPlayerTable[i].mPlayerID; msg.mRequest=QString("endupdate"); msg.mContent=QString("NULL"); struct sockaddr_in tempt; ConvertQStrToSockaddr(mPlayerTable[i].mAddr,mPlayerTable[i].mPort,tempt); Sender(msg,tempt); }}bool Master::ConvertQStrToSockaddr(QString addr, QString port, struct sockaddr_in &dstaddr){ dstaddr.sin_family=AF_INET; if(inet_pton(AF_INET, addr.ascii(), &dstaddr.sin_addr)<=0) { perror("inet_pton"); } dstaddr.sin_port=htons(port.toInt());}void Master :: AddPlayerTableEntry(QString ID, QString IP, QString Port){ int i=ID.toInt(); mPlayerTable[i].mPlayerID=ID; mPlayerTable[i].mAddr=IP; mPlayerTable[i].mPort=Port; //此处无需更新DeskTable }void Master ::AddPlayerChangeseatEntry(QString id, QString dsknum, QString side, QString curdsk, QString curside){ printf("in master::addplayerChangeseatentry , player id %s\n curdsk,side %s, %s\n chage to %s, %s\n", id.ascii(), curdsk.ascii(), curside.ascii(), dsknum.ascii(), side.ascii()); //更新playertable信息 int i= id.toInt(); mPlayerTable[i].mDeskNumber=dsknum; mPlayerTable[i].mSide=side; printf("in addplayerChangeseatentry, going to add side %s\n", side.ascii()); //更新DeskTable信息 int k=dsknum.toInt(); if(side.compare("white")==0) mDeskTable[k].mWhiteID=id; else mDeskTable[k].mBlackID=id; //清除旧信息 k=curdsk.toInt(); if(k==0) //第一次坐下, return; if(curside.compare("white")==0) mDeskTable[k].mWhiteID=QString("-1"); else mDeskTable[k].mBlackID=QString("-1");}void Master::AddPlayerQuitEntry(QString ID){ printf("in addplayerquitentry\n"); //update playertable int i=ID.toInt(); int dsknum=mPlayerTable[i].mDeskNumber.toInt(); QString side=mPlayerTable[i].mSide; mPlayerTable[i].mPlayerID=QString("-1"); mPlayerTable[i].mDeskNumber=QString("0"); mPlayerTable[i].mSide=QString("NULL"); //update desktable if(dsknum==0) return; if(side.compare("white")==0) mDeskTable[dsknum].mWhiteID=QString("-1"); else mDeskTable[dsknum].mBlackID=QString("-1"); }//处理客户登录请求int Master::HandleLogin(){ printf("in login\n"); int i=0; char ID[5]; //将地址,端口转换成字符 char addr[INET_ADDRSTRLEN]; char port[10]; int pot; strcpy(addr,inet_ntoa(mCliaddr.sin_addr)); pot=ntohs(mCliaddr.sin_port); sprintf(port,"%d",pot); //allocate ID,一号ID是服务器 for(i=2;i<MAX_PLAYER;i++) { if(mPlayerTable[i].mPlayerID.compare(QString("-1"))==0) break; } printf("in login i=%d\n",i); if(i>=MAX_PLAYER) return -1; else { sprintf(ID,"%d",i); } //modify mPlayerTable[] AddPlayerTableEntry(ID, QString(addr), QString(port)); //send feedback mMsgToSend.mID=QString("1"); mMsgToSend.mRequest=QString("login"); mMsgToSend.mContent=ID; printf("in login,going to send\n"); Sender(mMsgToSend, mCliaddr); //向所有客户更新大厅信息 UpdateHall(); }int Master::HandleQuit(){ int i; QString id=mMsgRecvd.mID; //找到ID for( i=2;i<MAX_PLAYER;i++) { if(mPlayerTable[i].mPlayerID.compare(id)==0) break; } //clear PlayerTable Entry AddPlayerQuitEntry(id); //向所有客户更新大厅信息表 UpdateHall(); }void Master ::HandleChangeseat(){ printf("in HandleChangeseat\n"); //解析数据,找到桌位号, 方向 char buffer[BUF_LEN]; int len; len=mMsgRecvd.mContent.length()+1; snprintf(buffer, len, "%s",mMsgRecvd.mContent.ascii()); printf("buffer:%s\n",buffer); char *ptr; int n=0; int i=0; ptr=&buffer[0]; while(ptr[i++]!='&') if(i>=len) printf("in handleChangeseat, get deskinfo error\n"); ptr[i-1]='\0'; QString dsknum = QString(&buffer[n]); n+=i; ptr=&buffer[0]; while(ptr[i++]!='&') if(i>=len) printf("in handleChangeseat, get deskinfo error\n"); ptr[i-1]='\0'; QString side = QString(&buffer[n]); n+=i; Message msg; printf("mDeskTable[dsknum.toInt()].mWhiteID %s\nmDeskTable[dsknum.toInt()].mBlackID %s\n side %s\n",mDeskTable[dsknum.toInt()].mWhiteID.ascii(),mDeskTable[dsknum.toInt()].mBlackID.ascii(), side.ascii()); //找到客户当前桌位信息,(含第一次坐下的情况) int index=mMsgRecvd.mID.toInt(); QString curdesk=mPlayerTable[index].mDeskNumber; QString curside=mPlayerTable[index].mSide; if(dsknum.compare(curdesk)==0&&side.compare(curside)==0) return ; //判断该座是否被占 发送reply信息 if(((mDeskTable[dsknum.toInt()].mWhiteID.compare("-1")==0 )&& (side.compare("white")==0)) ||((mDeskTable[dsknum.toInt()].mBlackID.compare("-1")==0 )&& (side.compare("black")==0))) { msg.mContent=QString("succeed"); //如果没有被占 //更新playertable信息 AddPlayerChangeseatEntry(mMsgRecvd.mID, dsknum, side, curdesk, curside); //让所有客户更新信息,这里是全部更新,应该是部分更新,待改进 UpdateHall(); } else msg.mContent=QString("failed"); msg.mID=QString("1"); msg.mRequest=QString("rechangeseat"); Sender(msg, mCliaddr); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -