⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hallmaster.cpp

📁 用qt写的网络五子棋程序
💻 CPP
字号:
#include "HallMaster.h"HallMaster::HallMaster(QWidget *parent, char *name)	:QWidget(parent, name){	mGamefaceOpened=false;	mOnline=false;	CreateSockFD();	mTimer =new QTimer(this, 0);	connect(mTimer, SIGNAL(timeout()), this, SLOT(sReceiver())); 	mOpID=QString("-1");}HallMaster::~HallMaster(){	}//接收数据的函数,由QTimer类的定时器每50ms驱动一次void HallMaster:: sReceiver(){	int recvnum,val;	val=fcntl(mSockFD, F_GETFL, 0);	fcntl(mSockFD,F_SETFL, val|O_NONBLOCK);	int i=0;	while(i++<10)	{  		recvnum=recvfrom(mSockFD, mRevBuf, BUF_LEN,0,0,0);  	 	if(recvnum==-1)   	 	{     			//perror("recvmsg");     			   	 	}  	 			else		{			printf("int receiver received!%s\n",mRevBuf);			//通知Disposer处理信息			Disposer();		}	}	mTimer->start( 50 );		}//将Message 格式的数据结构以udp数据包形式发送到dstaddrint HallMaster::Sender(Message msg,struct sockaddr_in dstaddr ){ 	 int sockfd,sendnum,len; 	char buffer[BUF_LEN];	len=mPackDisposer.MsgPacker(msg,buffer);	sockfd=socket(AF_INET,SOCK_DGRAM,0);  if(sockfd==-1)   {    perror("socket");    exit(1);   } 	sendnum =sendto(mSockFD,buffer,len,0,(struct sockaddr *)&dstaddr,sizeof(struct sockaddr));   	if(sendnum<0)	{		perror("sendto");	}		buffer[sendnum]='\0';	printf("send, %s  to %s, %d\n",buffer,inet_ntoa(dstaddr.sin_addr),ntohs(dstaddr.sin_port));return 0;}//创建套接字,收发使用同一个socket fdbool HallMaster::CreateSockFD(){			int sockfd;   	 	//准备连接 	sockfd=socket(AF_INET,SOCK_DGRAM,0); 	if(sockfd==-1)   	{    		perror("socket");    		   	}	mSockFD=sockfd;	}int HallMaster::SetServerAddr(QString ip){		mServerAddr.sin_family=AF_INET;	mServerAddr.sin_port=htons(1500);	inet_pton(AF_INET,ip.ascii() ,&mServerAddr.sin_addr);	}//Runner是驱动本类工作的函数int HallMaster::Runner(){	if(mOnline)	{		printf("still online!!!\n");		return 1;	}	mTimer->start( 50 );  	mMsgToSend.mID=QString("0000");  	mMsgToSend.mRequest=QString("login"); 		mMsgToSend.mContent=QString("F");        Sender(mMsgToSend, mServerAddr);  	}//分发器, 根据收到数据的请求调用相应函数处理,本函数由Receiver()调用int HallMaster::Disposer(){	Message msg;	mPackDisposer.MsgUnPacker(mMsgRecvd,mRevBuf);		//收到登录回复,得到ID	if(!mMsgRecvd.mRequest.compare(QString("login")))	{		mMyID=mMsgRecvd.mContent;		mOnline=true;				msg.mRequest=QString("hmyid");		msg.mContent=mMsgRecvd.mContent;		emit sendmsgtomain(msg);			}	//收到更新信息	else if(!mMsgRecvd.mRequest.compare(QString("update")))		UpdatePlayerTable();			//更新结束消息	else if(!mMsgRecvd.mRequest.compare(QString("endupdate")))	{					emit updatehall(); //一次性更新界面		return 5;          //5表示结束更新	}	//receive invitation, pass it to mMain to decide;	else if(!mMsgRecvd.mRequest.compare(QString("invite")))	{		msg.mRequest="hreplyinvite";		emit sendmsgtomain( msg);	}	//收到邀请回复,邀请信息在进入对局界面后按下棋盘下方"Start"时发出,"Start"按下时,先修改自己的状态为"Waiting",再发邀请	else if(!mMsgRecvd.mRequest.compare(QString("reinvite:agree")))	{				//记录对方addr,便于发送聊天信息,游戏数据		int index= mMsgRecvd.mID.toInt();		QString addr, port;		addr=mPlayerTable[index].mAddr;		port=mPlayerTable[index].mPort;		ConvertQStrToSockaddr(addr, port, mOpAddr);				//对局相关,交给Main处理		msg.mRequest=QString("hagreeinvite");		emit sendmsgtomain(msg);			}		//对方发来落子的坐标	else if(!mMsgRecvd.mRequest.compare(QString("putchess")))	{			//对局相关,交给Main处理		msg.mRequest = QString("hputchess");		msg.mContent = mMsgRecvd.mContent;		emit sendmsgtomain( msg );	}	//服务器发来换座(坐下)的回复	else if(!mMsgRecvd.mRequest.compare(QString("rechangeseat")))	{			//判断成功于否		printf("sitdown result in Content :%s\n",mMsgRecvd.mRequest.ascii());		if(mMsgRecvd.mContent.compare(QString("succeed"))==0)		//显示 交给Main下来完成,		{				msg.mRequest=QString("hchangeseat");			HandleSeatchanged(msg);								}		else			{printf("change seat failed!\n");}//提示失败	}		//对方发来聊天信息	else if(!mMsgRecvd.mRequest.compare(QString("chat")))	{			msg.mRequest = QString("recvchat");		msg.mContent = mMsgRecvd.mContent;		emit sendmsgtomain(msg);	}	else 	{		printf("unknown request!\n");	}	return 123;//该返回值无特定意义}//获取第i号player的idQString HallMaster::getPlayerID( int i ){	if(i>0&&i<MAX_PLAYER)		return mPlayerTable[i].mPlayerID;	else 		return QString("0");} //获取第i号player的座位号, "0"表示还没坐下QString HallMaster::getPlayerDesknumber( int i ){	if(i>0&&i<MAX_PLAYER)		return mPlayerTable[i].mDeskNumber;	else 		return QString("0");} //获取i号桌白方IDQString HallMaster :: getDeskWhiteside(int i){	if(i>0&&i<MAX_DESK)		return mDeskTable[i].mWhiteID;	else		return QString("0");}//获取I号桌黑方idQString HallMaster::getDeskBlackside(int i){	if(i>0&&i<MAX_DESK)		return mDeskTable[i].mBlackID;	else		return QString("0");	}QString HallMaster::getMyID(){	return mMyID;}QString HallMaster::getMyDesknumber(){	int i=0;	i=mMyID.toInt();	if(i>0)		return mPlayerTable[i].mDeskNumber;	else 		return QString("0");}//更新playertableint HallMaster::UpdatePlayerTable(){	//还原出一条PlayerTableNode	PlayerTableNode node;        char tempt[BUF_LEN];	strncpy(tempt,mMsgRecvd.mContent.ascii(),mMsgRecvd.mContent.length());	mPackDisposer.TableUnPacker(node,tempt);		//根据ID找到相应Player	int index;	index=node.mPlayerID.toInt();			//替换其中信息,为保持desktable一致性,先删除desktable的旧信息 	int k=mPlayerTable[index].mDeskNumber.toInt();	QString lastside=mPlayerTable[index].mSide;	if(k!=0)	{				if(lastside.compare("white")==0)			mDeskTable[k].mWhiteID="-1";		else			mDeskTable[k].mBlackID="-1";			}		mPlayerTable[index].mPlayerID=node.mPlayerID;	mPlayerTable[index].mPlayerState=node.mPlayerState;	mPlayerTable[index].mPlayerOpID=node.mPlayerOpID;	mPlayerTable[index].mAddr=node.mAddr;	mPlayerTable[index].mPort=node.mPort;	mPlayerTable[index].mDeskNumber=node.mDeskNumber;	mPlayerTable[index].mSide=node.mSide;	//更新mDeskTable,保持同步	 k=node.mDeskNumber.toInt(); //player所在桌号,0表示不在桌上	if(k==0)		return 0;	else		//判断方向		if(node.mSide.compare("white")==0)			mDeskTable[k].mWhiteID=node.mPlayerID;		else			mDeskTable[k].mBlackID=node.mPlayerID;			//根据mPlayerTable向mMain发送myDesk的桌位信息	index=mMyID.toInt();	k=mPlayerTable[index].mDeskNumber.toInt();	if(k==0)		return 0;	Message msg;	msg.mRequest=QString("hupdatedesk");	msg.mContent=mDeskTable[k].mWhiteID;	msg.mContent2=mDeskTable[k].mBlackID;	emit sendmsgtomain(msg);		return 0;}//向同一桌的对手发送邀请游戏信息void HallMaster::HandleSendInvite(){		//找到自己的桌位得到对方ID	int index=mMyID.toInt();	int dsknum=mPlayerTable[index].mDeskNumber.toInt();	QString id;	if(mDeskTable[dsknum].mWhiteID.compare(mMyID)==0)//找对方的id		id=mDeskTable[dsknum].mBlackID;	else		id=mDeskTable[dsknum].mWhiteID;		//根据ID查找对方地址 待改进	int i;	for(i=2; i<MAX_PLAYER; i++)	{		if(mPlayerTable[i].mPlayerID.compare(id)==0)			break;	}	if(i>=MAX_PLAYER)		printf("id not found!\n");			struct sockaddr_in dstaddr;	if(ConvertQStrToSockaddr( mPlayerTable[i].mAddr ,mPlayerTable[i].mPort ,dstaddr )==false)	{		printf("convertqstrtosockaddr failed!\n");		return;	} 		//发送"invite"请求	Message msg;	msg.mID=mMyID;	msg.mRequest=QString("invite");	msg.mContent=id;			Sender(msg, dstaddr);	}//将QString表示的IP地址和端口号转换成struct sockaddr, 协议一致为AF_INETbool HallMaster::ConvertQStrToSockaddr(QString addr, QString port, struct sockaddr_in &dstaddr){				if(addr.ascii()==NULL||port.ascii()==NULL)		return false;		dstaddr.sin_family=AF_INET;	if(inet_pton(AF_INET, addr.ascii(), &dstaddr.sin_addr)<=0)	{		perror("inet_pton");		return false;	}	dstaddr.sin_port=htons(port.toInt());	return true;	}//处理mMain::mChessBoard发送来的同意下棋的请求,将同意下棋邀请信息回复邀请方void HallMaster::HandleAgreeInvite(){	Message msg;	//得到邀请方ID,并查询对方地址	QString id=mMsgRecvd.mID;	int index=id.toInt();	QString addr=mPlayerTable[index].mAddr;	QString port=mPlayerTable[index].mPort;		//发送回复			struct sockaddr_in dstaddr;	msg.mID=mMyID;	msg.mRequest=QString("reinvite:agree");	msg.mContent="agree";			ConvertQStrToSockaddr(addr,port,dstaddr);	Sender(msg,dstaddr);	//记录对方addr	ConvertQStrToSockaddr(addr, port, mOpAddr);	}//本方下棋后传来落子坐标,在此处理void HallMaster::HandleChessput(Message msg){		//将坐标发送给对方	Message msgtosend;	msgtosend.mID=mMyID;	msgtosend.mRequest=QString("putchess");	msgtosend.mContent=msg.mContent+QString("#")+msg.mContent2+QString("#");	Sender(msgtosend, mOpAddr);			}//坐下或换座时向服务器发送请求坐下(换座)的请求void HallMaster:: HandleSendSitdown(QString dsknum, QString side){		Message msg;	msg.mID=mMyID;	msg.mRequest=QString("changeseat");	msg.mContent=dsknum+QString("&")+side+QString("&");	Sender(msg, mServerAddr);}//收到server回复,坐下(换座)成功,通知mMainvoid HallMaster:: HandleSeatchanged(Message msg){	//get myside and mydesknumber	int index=mMyID.toInt();	int k=mPlayerTable[index].mDeskNumber.toInt();	if(k<=0)		return ;	QString side;	if(mDeskTable[k].mWhiteID.compare(mMyID)==0)		side=QString("white");	else		side=QString("black");	msg.mRequest=QString("hchangeseat");	msg.mContent=side;	emit sendmsgtomain(msg);	emit showgameface();}//向对方发送聊天内容void HallMaster::HandleSendChat(Message msg){	msg.mID=mMyID;	msg.mRequest=QString("chat");	Sender(msg, mOpAddr);}//退出大厅时的处理函数void HallMaster:: sonquit(){	//check current state decide if it is valid to quit	if(mGamefaceOpened)		printf("please close gamewindow!\n");	//send request "quit" to server	Message msg;	msg.mID=mMyID;	msg.mRequest=QString("quit");		Sender(msg, mServerAddr);		//close and quit	emit quithall();}//处理内部消息的分发器void HallMaster::sdisposemsg(Message msg){	QString req=msg.mRequest;	//mMain::mChessBoard发来同意邀请下棋的请求	if(!req.compare("bagreeinvite"))	{		HandleAgreeInvite();	}	//mMain::mChessBoard发来邀请下棋的请求,转发给对方	else if(!req.compare("bsendinvite"))	{		printf("in hallmaster::disposemsg, going to handle bsendinvite\n");		HandleSendInvite();	}	//mMain::mChessBoard 发来落子消息	else if(!req.compare("bchessput"))	{		HandleChessput(msg);	}		//Hall 发来坐下请求,转发给服务器	else if(!req.compare("hallsitdown"))	{		HandleSendSitdown(msg.mContent, msg.mContent2);	}	//mMain::mChatBox发来聊天信息	else if(!req.compare("cchat"))	{		HandleSendChat(msg);	}	//Hall 发来设置服务器地址的消息	else if(!req.compare("hallsetserveraddr"))	{		SetServerAddr( msg.mContent);	}	else 		printf("hallmaster::disposemsg, unknown request! %s\n",msg.mRequest.ascii());}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -