非阻塞型TCP,也被称之为异步IO通信,当有数据到来时才触发读写操作。用SELECT机制可以轻易做到这一点,以下介绍其用法。
int init_TCP(char *ipaddr, char *iport)
{
int client_len;
fd_set read_fds;
int sock_fd, conn_fd;
int s32Ret;
struct timeval tv; //等待时长
tv.tv_sec = 30; // wait for 30s
tv.tv_usec = 0;
struct sockaddr_in addr_serv,addr_client;
sock_fd = socket(AF_INET,SOCK_STREAM,0);///tcp server
if(sock_fd < 0){
perror("socket");
exit(1);
} else {
printf("sock sucessful\n");
}
//初始化服务器端地址
memset(&addr_serv,0,sizeof(addr_serv));
addr_serv.sin_family = AF_INET;
addr_serv.sin_port = htons(iport);
addr_serv.sin_addr.s_addr =inet_addr(ipaddr);
client_len = sizeof(struct sockaddr_in);
int opt = 1;
setsockopt(sock_fd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));//允许TCP地址复用
if(bind(sock_fd,(struct sockaddr *)&addr_serv,sizeof(struct sockaddr_in))<0){
perror("bind");
exit(1);
}
else
{
printf("bind sucess\n");
}
if (listen(sock_fd,QUEUE_LINE) < 0)
{
perror("listen");
exit(1);
}
else
{
printf("listen sucessful\n");
}
printf("begin accept:\n");
FD_ZERO(&read_fds);//清空读
FD_SET(sock_fd, &read_fds);//将对应的SOCKET置位
**原本这里会发生阻塞的**///
//conn_fd = accept(sock_fd,(struct sockaddr *)&addr_client,&client_len);
s32Ret = select(sock_fd+1, &read_fds, NULL, NULL, &tv);
if (s32Ret < 0)
{
printf("select err\n");
return -1;
}
else if (0 == s32Ret)//超出设置的等待时长,发生异常
{
printf("time out\n");
return -1;
}
else
{
if (FD_ISSET(sock_fd, &read_fds))//如果套接字有数据到来,在此判断一下来源是否正确
{
conn_fd = accept(sock_fd,(struct sockaddr *)&addr_client,&client_len);//新的用户加入
printf("accept one client conn_fd is %d\n", conn_fd);
}
}
return conn_fd;
}