求助!关于linux下socket和FD_ISSET的使用。不胜感激!!
目的是编写一个连接ftp的客户端。
用cliopen(struct hostent * host, int port)建立了一个连接,函数如下
int cliopen(struct hostent *host, int port) //建立连接的函数,需要传入的参数为ip地址(域名)和端口号
{
int sockfd; //用来返回的描述符
int i;
struct sockaddr_in serv_addr; //establish a struct of the information of the server
bzero(&serv_addr, sizeof(serv_addr) );
serv_addr.sin_family = AF_INET; //使用TCP-IP协议
serv_addr.sin_port = htons(port); //使用21这个端口号
serv_addr.sin_addr = *( (struct in_addr *)host -> h_addr); //服务器的地址
if( (sockfd = socket(AF_INET, SOCK_STREAM, 0) ) == -1)
{
perror("socket创建失败!\n");
exit(1);
}
bzero( &(serv_addr.sin_zero), 8);
if( connect( sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr) ) == -1)
{
perror("error happens when connecting to serve! \n");
exit(1);
}
return sockfd;
}
在这里connect已经成功了。即已经连接上了ftp的服务器端。并且使用此函数返回的sockfd作为参数执行给服务器传命令的函数。函数如下:
void cmd_tcp(int sockfd) //这里是命令连接的操作过程
{
int maxfdp1, nread, nwrite, fd, replycode;
fd_set rset;
FD_ZERO(&rset); //先将描述符集清零
maxfdp1 = sockfd + 1; /* check descriptors [0..sockfd] */
int tag = 0;
for ( ; ; )
{
FD_SET(STDIN_FILENO, &rset); //将键盘的输入信息(用户命令)流加入到rset中
FD_SET(sockfd, &rset); //将连接主机的套接字(服务器响应)加入到rset中
if (select(maxfdp1, &rset, NULL, NULL, NULL) < 0) //当rset中有描述符被改变时,则select立即返回,现在是空转忙等待
printf("select error\n");
if (FD_ISSET(STDIN_FILENO, &rset)) //检测是否有键盘输入
{
....
}
if (FD_ISSET(sockfd, &rset)) //检测sockfd是否变化
{
....
}
}
}
问题1:在建立了连接得到sockfd以后,再把sockfd传入到这个函数中来并加入到rset,是不是根本检测不到之前的连接信息?也就是说如果ftp服务器返回了一个指令,到了cmd_tcp里面是不会select到的?
问题2:是否应该在for里面写上FD_SET(STDIN_FILENO, &rset); 和 FD_SET(sockfd, &rset); ?这样每次检测信息做出相应操作后都会让他们重新加入到rset中,为什么要这样做?是第一个参数类似一个数组或是什么东西吗?加入后如果同之前有变化就会检测出来?
超级大菜鸟,词不达意,理解万岁!