您的位置:首页 > 其它

练习C之SELECT形式的非阻塞IO

2015-11-20 13:39 274 查看
呵呵,理解得不深,但毕竟手打全版,且无错。但select.h不知何处找头文件,

粘下来作个记录。

POLL,EPOLL感觉代码类似,只是函数和系统实现不一样,,EPOLL目前最合理的。定位精确,算法复杂度最好。

#include "select.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/types.h>

typedef struct _CLIENT{
int fd;
struct sockaddr_in addr;
} CLIENT;

#define MYPORT 59000

#define BACKLOG 5

CLIENT client[BACKLOG];

int currentClient = 0;

#define REVLEN 10
char recvBuf[REVLEN];

void showClient();
int main()
{
int i, ret, sinSize;
int recvLen = 0;
fd_set readfds, writefds;
int sockListen, sockSvr, sockMax;
struct timeval timeout;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;

for(i=0; i<BACKLOG; i++)
{
client[i].fd = -1;
}

printf("accept started\n");

//socket
if ((sockListen = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("socket error\n");
return -1;
}

bzero(&server_addr, sizeof(server_addr));

server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(MYPORT);

//bind
if(bind(sockListen, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0)
{
printf("bind error\n");
return -1;
}

//listen
if(listen(sockListen, 5)< 0)
{
print("listen error\n");
return -1;
}

for(i=0; i<BACKLOG; i++)
{
client[i].fd = -1;
}

//select
while(1)
{
FD_ZERO(&readfds);
FD_SET(sockListen, &readfds);
sockMax = sockListen;

for(i=0; i<BACKLOG; i++)
{
if(client[i].fd > 0)
{
FD_SET(client[i].fd, &readfds);
if(sockMax<client[i].fd)
{
sockMax = client[i].fd;
}
}
}

timeout.tv_sec = 3;
timeout.tv_usec = 0;

ret = select((int)sockMax+1, &readfds, NULL, NULL, &timeout);
if(ret < 0)
{
printf("select error\n");
break;
}
else if(ret == 0)
{
printf("timeout...\n");
continue;
}
printf("test111\n");

for(i=0; i<BACKLOG; i++)
{
if(client[i].fd>0 && FD_ISSET(client[i].fd, &readfds))
{
if(recvLen != REVLEN)
{
while(1)
{
ret = recv(client[i].fd, (char *)recvBuf+recvLen, REVLEN-recvLen, 0);
if(ret == 0)
{
client[i].fd = -1;
recvLen = 0;
break;
}
else if(ret < 0)
{
client[i].fd = -1;
recvLen = 0;
break;
}

recvLen = recvLen + ret;
if(recvLen < REVLEN)
{
continue;
}
else
{
printf("%s, buf = %s\n", inet_nota(client[i].addr.sin_addr), recvBuf);
recvLen = 0;
break;
}
}
}
}
}

if(FD_ISSET(sockListen, &readfds))
{
printf("isset\n");
sockSvr = accept(sockListen, NULL, NULL);

if(sockSvr == -1)
{
printf("accept error\n");
}
else
{
currentClient++;
}

for(i=0; i< BACKLOG; i++)
{
if(client[i].fd < 0)
{
client[i].fd = sockSvr;
client[i].addr = client_addr;
printf("You got a connection from %s \n", inet_ntoa(client[i].addr.sin_addr));
break;
}
}
}
}

printf("test\n");
return 0;
}

void showClient()
{
int i;
printf("client count = %d\n", currentClient);

for(i=0; i<BACKLOG; i++)
{
printf("[%d] = %d", i, client[i].fd);
}
printf("\n");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: