有人可以告诉我为什么以下代码不起作用吗?
#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()数据。我找不到问题的根源,有人可以帮助我吗?
答案 0 :(得分:1)
问题是读取循环,当你读取你收到的字节时,但是当你完成后,你会尝试再次接收,使recv
阻止。您需要使套接字无阻塞。不,阻塞/非阻塞状态不从被动侦听套接字继承。