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

📄 server.cpp

📁 用qt写的网络五子棋程序
💻 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 + -