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

📄 temp.c

📁 C++编写的一个聊天的小程序
💻 C
字号:
int main(int argc ,char *argv) 
{ 
	int			connfd,sockfd;
	int			acceptNum=0;
	struct sockaddr_in     client_addr; 
	int			bufSize;
	int			bNodelay = 1;
	int			bufSizeof;
	int			bufferSize;

	/*线程变量定义*/

	int			ret_main,j;
			/*网络属性定义*/
	int		isSocketAliveTime;					//keepalive值
	struct linger linger = { 0 };				//设置 socketopt 选项
	struct timeval tv;
	Message			*messageDeamon;
	int			readsize;						//读取数据包尺寸	
	char const * pidfile;
	//int			tcountDesk=0;
	//----------  2005-3-1-----------
	#ifdef LOOKASIDE
	//初始化旁观,删除旧的文件
	init_filelist();
	#endif


	//#################### 初始化网络 #######################	

	//init sockaddr
	 bzero(&client_addr,sizeof(struct sockaddr_in)); 
	 client_addr.sin_family=AF_INET; 
	 client_addr.sin_port=htons(4058); 
	 client_addr.sin_addr.s_addr=htonl(INADDR_ANY); 

	// 创建服务端 端口
	if((listen_fd=socket(AF_INET,SOCK_STREAM,0))<0) 
	  { 
			printf("Socket Error:%s\n\a",strerror(errno)); 
			exit(1); 
	  }   
	 printf("This is in the main:creat Socket successful!\nLAIZI_PORT = %d\n",4058);

	// 设置地址重用
	
	int val;

	if(listen_fd != -1){
		val = 1;
		ret_main = setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
		if(ret_main < 0) //printf("设置 地址重用 成功\n");
			printf("\t设置 地址重用 失败!!!\n");
	}
	
	n=1;	 
	 /* 如果服务器终止后,服务器可以第二次快速启动而不用等待一段时间  */ 
	 //setsockopt(listen_fd,SOL_SOCKET,SO_REUSEADDR,&n,sizeof(int)); 
	if(bind(listen_fd, (struct sockaddr *)&client_addr, sizeof(client_addr)) < 0){ 
		printf("Bind Error:%s\n\a",strerror(errno)); 
		//释放共享内存 实际程序不会运行到此处
		exit(1); 
	} 
	if(listen(listen_fd, MAX_LISTEN_CONNECT) < 0){
		printf("Listen Error:%s\n\a",strerror(errno)); 
		//释放共享内存 实际程序不会运行到此处
		exit(1); 
	}

	while(1) 
	{ 		

		//设置poll监听数据和连接
		//nReady = poll(client,maxPoll+1,INFTIM);
		nReady = poll(client, maxPoll+1, GAME_HEART_BEAT);
		#ifdef DEBUG
			//printf("◎◎◎ nReady = %d ◎◎◎\n",nReady);
			//fflush(stdout);
		#endif
		if(nReady <= 0){
			continue;
		}

		//*******************有新的socket连接**********************
		if(client[0].revents & POLLRDNORM){				
			memset(&caddr, 0, sizeof(caddr));				
			clilen = sizeof(caddr);
			//connfd = accept(listen_fd,NULL,NULL);
			connfd = accept(listen_fd, (struct sockaddr *)&caddr, &clilen);
			if(connfd < 0){
				//新连接描述符不正确
				printf("新连接描述符不正确, connfd = %d\n", connfd);
			}else if(connfd >= MAX_CONNECT){
				close(connfd);
				continue;
			}else{
				//判断是否为封ip的用户地址

				//连接网络属性设置
				//设置socket KeepAlive 时间
				
				isSocketAliveTime = 1;
				ret_main = setsockopt(connfd, SOL_SOCKET, SO_KEEPALIVE, &isSocketAliveTime, sizeof(isSocketAliveTime));					
				if(ret_main < 0){
					printf("\t设置 新连接 SO_KEEPALIVE 周期为 %d 秒 失败!!!\n", isSocketAliveTime);
				}
				
				//设置close关闭是否等待  heqingni 2004-11-30
				linger.l_onoff = 0;
				linger.l_linger = 0;
				ret_main = setsockopt(connfd, SOL_SOCKET, SO_LINGER, (const char *)&linger, sizeof(linger));
				if (ret_main == -1){
					//perror("设置 socket close不等待失败!\n");
					printf("设置 新连接socket close不等待 失败!!!\n");
				}

				
				//设置发送超时,避免一直等待  heqingni 2004-11-30
				tv.tv_sec = 0;
				tv.tv_usec = 300000;	//300毫秒
				ret_main = setsockopt(connfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
				if (ret_main == -1){
					//perror("设置 socket 发送超时时间=300毫秒 失败!!!\n");
					printf("设置 socket 发送超时时间=300毫秒 失败!!!\n");
				}
				/***
				tv.tv_sec=0;
				tv.tv_usec=600000;	//600毫秒
				ret_main = setsockopt(connfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
				if (ret_main == -1){
					//perror("设置 socket 发送超时时间=300毫秒 失败!!!\n");
					printf("设置 socket 接收超时时间=300毫秒 失败!!!\n");
				}		
				***/			
				//可以考虑设置为非阻塞式
				
				//-----------------------相应新的连接对象---------------------------
				i=1;
				j=0;
				while((j==0) && (i<=MAX_CONNECT)){
					if (( *(gameUser_map+i) ).isUsed == -1){
						client[i].fd = connfd;
						client[i].events = POLLRDNORM;
						//client[i].revents = 0; //bighead 2005-3-4

						//初始化连接对象
						( *(gameUser_map+i) ).tcp_sock = connfd;
						( *(gameUser_map+i) ).tcp_addr = caddr.sin_addr.s_addr; // inet_ntoa(caddr.sin_addr)-->char IP
						( *(gameUser_map+i) ).tcp_port = caddr.sin_port;
						( *(gameUser_map+i) ).life = 2;		//获得初始生命值 2 * 10 =30点	
						( *(gameUser_map+i) ).status = ROM_CONNED_STATE;	//连接,未登陆						
						( *(gameUser_map+i) ).isUsed = 1;
						j=1;
					}else{
						i++;
					}
				}
					
				if( i > MAX_CONNECT ){
					printf("出错: MAX USER ACHIEVD =%d!!!!!!!!!\n",MAX_CONNECT);
					close(connfd);
				}else{	//动态分配新的空间
					if(i > maxPoll){
						maxPoll = i;
					}

					#ifdef DEBUG
						printf("New Connection: index = %d\n",i);
					#endif
				}					

				//如果只有一个新的连接,没有数据,则退出当前循环,进入下一次循环
				nReady=nReady-1;
				if(nReady <= 0){
					continue;
				}
			}
		}
		
		//*******************end有新的socket连接********************************
		#ifdef DEBUG
			/**
		x_Debug = 0;
		for(i=0;i <= maxPoll;i++){
			if((sockfd = client[i].fd) > 0){
				x_Debug++;
			}
		}
		printf("当前sock总数 : %d\n",x_Debug);
		**/
		#endif

		//*******************检查所有端口,是否有数据可以读取*******************
		for(i=1; i<=maxPoll; i++){
			if((( *(gameUser_map+i) ).isUsed ==1) && (( *(gameUser_map+i) ).status >= ROM_CONNED_STATE)){
				//连接已经断开
				if((sockfd = client[i].fd) < 0){
					/*关闭连接*/
					if( ((*(gameUser_map+i)).status > ROM_WAIT_QUIT)&& ((*(gameUser_map+i)).status != RE_LOGINED))
					{
						(*(gameUser_map+i)).status = ROM_WAIT_QUIT;
					}
					//close_GameUser(&(*(gameUser_map+i)), i);
					continue;
				}else{
					if (client[i].revents != 0){
						//描述字不是一个打开的文件
						if (client[i].revents & POLLNVAL){
							#ifdef DEBUG
							printf("描述字出错!!! fd=%d user=%s,uindex=%d\n", client[i].fd, ( *(gameUser_map+i) ).name, ( *(gameUser_map+i) ).uindex);
							#endif					
							client[i].revents = 0;
							/*关闭连接*/
							if ((*(gameUser_map+i)).status > ROM_WAIT_QUIT)
							{
								(*(gameUser_map+i)).status = ROM_WAIT_QUIT;
							}
							//close_GameUser(&(*(gameUser_map+i)), i);
						}else{
							//正常处理
							if(client[i].revents & ( POLLRDNORM | POLLERR | POLLHUP )){	
								#ifdef DEBUG
								printf("在读取数据中:i = %d ....\n",i);
								#endif
								if (( *(gameUser_map+i) ).insize >0){
									readsize=( *(gameUser_map+i) ).insize;	//如果上次没有读完,那么继续读
								}else{
									readsize=bufferSize;					//否则,读去规定长度的包
								}
							
								if((msgSize = recv(sockfd, (void *)buffer, readsize, 0)) < 0){
									//perror("Recv出错!!!\n"); //errno
									printf("接收数据<0!!! fd=%d user=%s,uindex=%d\n",client[i].fd,( *(gameUser_map+i) ).name,( *(gameUser_map+i) ).uindex);
									if(	errno==EINTR 
										|| errno==EAGAIN 
										|| errno==EWOULDBLOCK 
										|| errno==ENOMEM 
										|| 0) 
									{
										/* 系统限制错误,等待重试 */
									}else{
										client[i].revents = 0;						
										/*关闭连接*/	//查找同一桌的用户 将用户的断开发送给其他 同一桌用户
										if ((*(gameUser_map+i)).status > ROM_WAIT_QUIT)
										{
											if (((*(gameUser_map+i)).status != RE_LOGINED))
											{
												(*(gameUser_map+i)).status = ROM_WAIT_QUIT;
											}
											else
											{
												//2005-12-15  多次重新连接时候 防止被踢
												close(client[i].fd);
												client[i].fd = -1;
												printf("接收数据<0!!!重新连接时候 防止被踢  fd=%d user=%s,uindex=%d\n",client[i].fd,( *(gameUser_map+i) ).name,( *(gameUser_map+i) ).uindex);
											}
										}
										//close_GameUser(&(*(gameUser_map+i)), &deskArr[( *(gameUser_map+i) ).deskIndex]);
									}
								}else if(msgSize == 0){
									printf("接收数据=0 fd=%d,user=%s,uindex=%d,msgSize=%d\n", client[i].fd, ( *(gameUser_map+i) ).name, ( *(gameUser_map+i) ).uindex,msgSize);
								
									client[i].revents = 0;								
									/*关闭连接*/ //查找同一桌的用户 将用户的断开发送给其他 同一桌用户
									if ((*(gameUser_map+i)).status > ROM_WAIT_QUIT)
									{
										(*(gameUser_map+i)).status = ROM_WAIT_QUIT;
									}
									//close_GameUser(&(*(gameUser_map+i)), &deskArr[( *(gameUser_map+i) ).deskIndex]);
									//远程连接断开
								}else{ //正常读取数据
									//client[i].revents = 0;//可能同时到达多个数据包,但是一次只读一个
									/*添加接收到的数据到缓冲*/
									ret_main=read_data_incache(msgSize,bufferSize,&(*(gameUser_map+i)),buffer);
									printf("接收数据中 fd=%d,user=%s msgSize=%d\n", client[i].fd, ( *(gameUser_map+i) ).name,msgSize);
									if(ret_main < 0){	//接收数据异常
										if ((*(gameUser_map+i)).status > ROM_WAIT_QUIT)
										{
											(*(gameUser_map+i)).status = ROM_WAIT_QUIT;
										}
										//close_GameUser(&(*(gameUser_map+i)), &deskArr[( *(gameUser_map+i) ).deskIndex]);	/*关闭连接*/
									}

									if (ret_main==0){	//接收到完整的数据包,否则继续等待下一次读取
										messageDeamon = &((*(gameUser_map+i)).intmp);
										//预处理
										ret_main=pre_decode(&(*(gameUser_map+i)),messageDeamon,i);									
										
										if (ret_main > 0 )	//等待进一步数据库处理
										{
											/*添加接收到的数据到处理队列中*/
											add_data_inqueue(&(*(gameUser_map+i)));
											//printf("添加 处理数据中完毕!!\n");
										}
										if (ret_main < 0)	//预处理发现非法指令
										{
											/*关闭连接*/
											//printf("清除 用户完毕!!\n");
											if ((*(gameUser_map+i)).status > ROM_WAIT_QUIT)
											{
												(*(gameUser_map+i)).status = ROM_WAIT_QUIT;
											}
										}
										

									}
											
								}	
							}
						}// 退出socket正常读取数据
					}// 描述字不是一个打开的文件
					nReady=nReady-1;
					if(nReady <= 0){
						continue;	// 如果已经没有相应事件,则不需要继续检查
					}
				}
			}// 合法判断				
		}// 退出for循环
			//*******************end检查所有端口,是否有数据可以读取*******************
	}// exit while(1)
	//释放共享内存
	//free(gameUser_map);
	free(roomUnit);
	free(romMatchResult);
	//free(GameUnit);
	//munmap( gameUser_map, sizeof(CtrUser)*MAX_CONNECT );

	/*系统关闭*/
    eventlog(eventlog_level_info, "main","server has shut down");
    if(pidfile){
		if (remove(pidfile) < 0){
			eventlog(eventlog_level_error, "main","could not remove pid file \"%s\" (remove: %s)", pidfile, strerror(errno));
		}
		free((void *)pidfile); /* avoid warning */
    }

	eventlog_close();	
}  



void SendMsg()
{
	int writesize,written_bytes,write_left;
	int i,j,n,ret;	
	char ptr[sizeof(Message)];
	Message *ptr_Msg;

	printf("Init SendMsg=%d Successful!\n",getpid());
	fflush(stdout);

	while(1)
	{
		for(i = 1;i <= maxPoll;i++)
		{
			if ((( *(gameUser_map+i) ).isUsed ==1) && (( *(gameUser_map+i) ).status >= ROM_CONNED_STATE))
			{

			//连接已经断开
			if(client[i].fd < 0)
			{
				/*关闭连接*/
				if ( ((*(gameUser_map+i)).status > ROM_WAIT_QUIT) && ((*(gameUser_map+i)).status != RE_LOGINED))
				{
					(*(gameUser_map+i)).status = ROM_WAIT_QUIT;
					printf("发送数据关闭连接 user=%s,uindex=%d\n", ( *(gameUser_map+i) ).name, ( *(gameUser_map+i) ).uindex);
				}
			}else{
			
			ret=read_data_outqueue(&(*(gameUser_map+i)),&ptr,&ptr_Msg,&writesize);
			if (ret>0)
			{
				if (ret==2)
				{
					written_bytes=send((*(gameUser_map+i)).tcp_sock,ptr_Msg,writesize,MSG_NOSIGNAL); 
				}else{
					written_bytes=send((*(gameUser_map+i)).tcp_sock,ptr,writesize,MSG_NOSIGNAL); 
				}
				if (written_bytes<0)	//出现错误
				{
					//perror("Send出错!!!\n"); //errno
					printf("发送数据<0!!! fd=%d user=%s,uindex=%d\n",( *(gameUser_map+i) ).tcp_sock,( *(gameUser_map+i) ).name,( *(gameUser_map+i) ).uindex);
					if (		errno==EINTR ||
								errno==EAGAIN ||
								errno==EWOULDBLOCK ||
								errno==ENOMEM ||
						0) /* 系统限制错误,等待重试 */
					{
						
					}else{						
						/*出错,关闭连接*/
						printf("Socket=%d error!\n",( *(gameUser_map+i) ).tcp_sock);
						if ((*(gameUser_map+i)).status > ROM_WAIT_QUIT)
						{
							(*(gameUser_map+i)).status = ROM_WAIT_QUIT;
						}
					}
				}else if (written_bytes==0) //没有发送出去
					{
						/*出错,关闭连接*/
						printf("Socket=%d error!\n",( *(gameUser_map+i) ).tcp_sock);
						if ((*(gameUser_map+i)).status > ROM_WAIT_QUIT)
						{
							(*(gameUser_map+i)).status = ROM_WAIT_QUIT;
						}
					}else{					//正常发送,判断是否发送全部完成,否则,留着下一次发送
							if (written_bytes>writesize)
							{
								/*出错,关闭连接*/
								printf("Socket=%d error!\n",( *(gameUser_map+i) ).tcp_sock);
								if ((*(gameUser_map+i)).status > ROM_WAIT_QUIT)
								{
									(*(gameUser_map+i)).status = ROM_WAIT_QUIT;
								}
							}else{
								if (written_bytes < writesize)
								{//仍然没有发送完,等着下一次继续发送
									write_left=writesize-written_bytes;
									if (ret==2)
										memcpy(ptr,ptr_Msg,writesize);
									for (j=0; j<write_left; j++)
										( *(gameUser_map+i) ).outcache[j]=*(ptr+(written_bytes+j));
									
									( *(gameUser_map+i) ).outsize=write_left;
								}else{
									( *(gameUser_map+i) ).outsize=0;
									#ifdef DEBUG
										printf("Send:userid=%s cmd=%d  i=%d Successfully!\n",( *(gameUser_map+i) ).name,ntohs(ptr_Msg->cmd),i);
									#endif
								}
							}
						}
			}//是否有数据需要发送		
			}
			}//合法性判断
		}//end of for
		usleep(GAME_HEART_BEAT);	//休息20毫秒
	}
}

⌨️ 快捷键说明

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