3
回答
我用Epoll写的socket服务器,持续接受数据经常接收错误的数据,各位大神帮忙解决一下!有好用的实例给发一个yushadow@126.com
终于搞明白,存储TCO原来是这样算的>>>   
#include "test.h"


int iEpollfd = 0;
struct epoll_event Epoll_ev;
struct epoll_event Epoll_events[EPOLLMAXNUM];

int main()
{
	int iRetvalue = 0;


	while(TRUE)
	{
		iRetvalue = server_init(); 
		if(0 > iRetvalue)
		{
			sleep(3);
		}

		continue;
	}
	

	return 0;
}

static int server_init()
{
	int iRetvalue = 0;
	int iServerfd = 0;
	int iClientfd = 0;
	int iRetfds   = 0;
	int i;
	char recvbuf[1024] = "\0";

	struct sockaddr_in Clientaddr;
	socklen_t socklen = sizeof(struct sockaddr_in);
	memset(&Clientaddr, 0, sizeof(Clientaddr));

	iServerfd = socket_init();
	if(0 > iServerfd)
	{
		printf("socket init error\n");
		return -1;
	}

	int iCount = 0;

	while(TRUE)
	{
		iRetfds = epoll_wait(iEpollfd, Epoll_events, EPOLLMAXNUM, 0);
		for(i = 0; i < iRetfds; i++)
		{
			if(0 > (iClientfd == Epoll_events[i].data.fd)) continue;
			if(iServerfd == Epoll_events[i].data.fd)
			{
				iClientfd = accept(iServerfd, (struct sockaddr*)&Clientaddr, &socklen);
				if(0 > iClientfd)
				{
					iRetvalue = errno;
					printf("[%s][%s][%d]:accept error:%s\n", __FILE__, __func__, __LINE__, strerror(errno));
					break;
				}
				printf("客户端[ %d ]连接成功\n", iClientfd);

				socket_setnonblock(iClientfd);    

				Epoll_ev.data.fd = iClientfd;                            //设置与处理事件相关的描述符
				Epoll_ev.events  = EPOLLIN|EPOLLET;                              //设置要处理的事件类型
				epoll_ctl(iEpollfd, EPOLL_CTL_ADD, iClientfd, &Epoll_ev);  //注册epoll事件

				continue;
			}//end if

			if(Epoll_events[i].events&EPOLLIN)
			{
				iClientfd = Epoll_events[i].data.fd;
				//printf("iClientfd = %d\n", Epoll_events[i].data.fd);
				int iTotallen = 0;
				int iOnce = 0;
				do
				{
					/*
					iOnce = recv(iClientfd, &iTotallen, 4, 0);
					if(4 != iOnce)
					{
						printf("接收长度错误!\n");
						break;
					}
					printf("------------长度: %d\n", iTotallen);
*/
					memset(&recvbuf, 0, sizeof(recvbuf));
					//iOnce = recv(iClientfd, recvbuf, iTotallen, 0);
					iOnce = recv(iClientfd, recvbuf, 1024, 0);
					if(iOnce != 621)
					{
						printf("接收错误");
						break;
					}

					//printf("%s:socket:%d\n",recvbuf,iClientfd);
					iCount++;
					printf("iCount = %d\n", iCount);
				}
				while(0);

				Epoll_ev.data.fd = iClientfd;                            //设置与处理事件相关的描述符
				Epoll_ev.events  = EPOLLIN|EPOLLET;                       //设置要处理的事件类型
				epoll_ctl(iEpollfd, EPOLL_CTL_ADD, iClientfd, &Epoll_ev);  //注册epoll事件
			}// end if
		}//end for
	}//end while

	close(iServerfd);
	return 0;
}


static int socket_init()
{
	int iRetvalue = 0;

	int iSockfd = 0;
	struct sockaddr_in Serveraddr;
	socklen_t socklen = sizeof(struct sockaddr_in);

	memset(&Serveraddr, 0, sizeof(Serveraddr));
	Serveraddr.sin_family = AF_INET;
	Serveraddr.sin_port   = htons(SERVER_PORT);
	Serveraddr.sin_addr.s_addr = htonl(SERVER_ADDR); 

	iSockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(0 > iSockfd)
	{
		printf("create socket error\n");
		return -1;
	}

	iEpollfd = epoll_create(EPOLLMAXNUM);
	if(0 > iEpollfd)
	{
		printf("create epoll error\n");
		close(iSockfd);
		return -1;
	}

	Epoll_ev.data.fd = iSockfd;                            //设置与处理事件相关的描述符
	Epoll_ev.events  = EPOLLIN|EPOLLET;                              //设置要处理的事件类型
	epoll_ctl(iEpollfd, EPOLL_CTL_ADD, iSockfd, &Epoll_ev);  //注册epoll事件


	iRetvalue = socket_setnonblock(iSockfd);       //把socket设置为非阻塞,epoll的边缘出发模式需要。
	if(iRetvalue)
	{
		printf("[%s][%s][%d]:设置非阻塞模式失败%s\n", __FILE__, __func__, __LINE__, strerror(errno));
		close(iSockfd);
		return -1;
	}

	iRetvalue = bind(iSockfd, (struct sockaddr *)&Serveraddr, socklen);
	if(iRetvalue)
	{
		printf("[%s][%s][%d]:bind error: %s\n", __FILE__, __func__, __LINE__, strerror(errno));
		close(iSockfd);
		return -1;
	}

	iRetvalue = listen(iSockfd, LISTENQ);
	if(iRetvalue)
	{
		printf("[%s][%s][%d]:listen error: %s\n", __FILE__, __func__, __LINE__, strerror(errno));
		close(iSockfd);
		return -1;
	}

	printf("监听socket成功 : %d\n", iSockfd);
	printf("请耐心等待连接.......\n");

	return iSockfd;
}

static int socket_setnonblock(int iSockfd)
{
	int iOpts = fcntl(iSockfd, F_GETFL);  //得到原有的句柄属性
	if(iOpts < 0)
	{
#ifdef PRINT
		printf("[%s][%s][%d]:fcntl error: %s\n", __FILE__, __func__, __LINE__, strerror(errno));
#endif
		return -1;
	}

	iOpts = iOpts|O_NONBLOCK;             //在原有属性的基础上添加非阻塞属性
	if(fcntl(iSockfd, F_SETFL, iOpts)<0)
	{
#ifdef PRINT
		printf("[%s][%s][%d]: fcntl error: %s\n", __FILE__, __func__, __LINE__, strerror(errno));
#endif
		return -1;
	}

	return 0;
}
举报
yushadow
发帖于4年前 3回/1K+阅

以下是问题补充:

  • @yushadow :哪位大神有好用的实例给发一个呗,邮箱yushadow@126.com (4年前)
顶部