[英]non-blocking I/O with select()
有人可以告訴我為什么以下代碼不起作用嗎?
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/time.h>
#include <errno.h>
int main(int argc, char **argv)
{
int sockfd, i, new = 0, maxfd, nready, on = 1;
struct sockaddr_in saddr;
ssize_t nbytes;
fd_set rfds, master;
char buffer[BUFSIZ];
if(-1 == (sockfd = socket(PF_INET, SOCK_STREAM, 0)))
{
perror("socket()");
exit(EXIT_FAILURE);
}
if(-1 == (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on))))
{
perror("setsockopt()");
exit(EXIT_FAILURE);
}
if(-1 == (fcntl(sockfd, F_SETFD, O_NONBLOCK)))
{
perror("fcntl()");
close(sockfd);
exit(EXIT_FAILURE);
}
(void)memset(&saddr, '\0', sizeof(struct sockaddr_in));
saddr.sin_port = htons(1234);
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
saddr.sin_family = AF_INET;
if(-1 == (bind(sockfd, (struct sockaddr*)&saddr, sizeof(saddr))))
{
perror("bind()");
close(sockfd);
exit(EXIT_FAILURE);
}
if(-1 == (listen(sockfd, 32)))
{
perror("listen()");
close(sockfd);
exit(EXIT_FAILURE);
}
FD_ZERO(&rfds);
FD_ZERO(&master);
maxfd = sockfd;
FD_SET(sockfd, &master);
printf("maxfd = %d\n", maxfd);
for(;;)
{
(void)printf("select()ing...\n");
(void)memcpy(&rfds, &master, sizeof(master));
if(-1 == (nready = select(maxfd+1, &rfds, NULL, NULL, NULL)))
{
perror("select()");
close(sockfd);
exit(EXIT_FAILURE);
}
for(i=0; i<FD_SETSIZE; i++)
{
if(FD_ISSET(i, &rfds))
{
if(i == sockfd)
{
(void)printf("trying to accept new connection(s)\n");
for(;;)
{
new = accept(sockfd, NULL, NULL);
if(new < 0)
{
if(errno != EWOULDBLOCK)
{
perror("accept()");
exit(EXIT_FAILURE);
}
/* no incomming connection */
break;
}
FD_SET(new, &master);
if(maxfd < new)
new = maxfd;
(void)printf("%d was added to set\n", new);
}
}
else
{
for(;;)
{
(void)printf("trying to read data from ready socket(s)\n");
while((nbytes = recv(i, buffer, sizeof(buffer), 0)) > 0)
printf("%s", buffer);
if(nbytes < 0)
{
if(nbytes != EWOULDBLOCK)
{
perror("recv()");
exit(EXIT_FAILURE);
}
break;
}
if(0 == nbytes)
{
close(i);
break;
}
FD_CLR (i, &master);
}
}
}
}
}
return 0;
}
它在*:1234上偵聽新連接。 它構建良好,沒有任何錯誤或警告,但無法從就緒描述符中接收數據。 我找不到問題的根源,有人可以幫助我嗎?
問題是讀取循環,當您讀取接收到的字節時,但是這樣做之后,您嘗試再次接收,從而使recv
成為塊。 您需要使套接字無阻塞。 不,阻止/非阻止狀態不是從被動偵聽套接字繼承的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.