这是我的服务器代码,不知道我是怎么做的
failed to select : Invalid argument
它在我的Mac上工作正常,但不在linux上。 谁能告诉我我哪里做错了?
我只是c编程中的新begynniner。
server.c
int server(int port){
int request_sd, newfd;
socklen_t clientaddrlen;
fd_set masterList;
fd_set readFd;
int bind_adress = 0, listen_connect = 0;
int fd_max;
int select_client, i;
struct sockaddr_in server_adr;
struct sockaddr_in client_adr;
if (!getcwd(root_path, PATH_LEN))
{
perror("set path");
}
request_sd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (request_sd < 0)
{
perror("failed: ");
return -1;
}else printf("create new socket i complete: %d\n", request_sd);
memset(&server_adr, 0 , sizeof (struct sockaddr_in));
server_adr.sin_family = AF_INET;
server_adr.sin_addr.s_addr = INADDR_ANY;
server_adr.sin_port = htons(port);
int activate = 1;
if (setsockopt(request_sd, SOL_SOCKET, SO_REUSEADDR, &activate, sizeof(int)) == -1)
{
perror("setsockopt: ");
return -1;
}
bind_adress = bind(request_sd, (struct sockaddr*) &server_adr, sizeof(struct sockaddr_in));
if (bind_adress < 0 )
{
perror("failed to bind : ");
return -1;
}
listen_connect = listen(request_sd, 10);
if (listen_connect <0)
{
perror("failed to listen : ");
return -1;
}
printf("\nListening for connections on port: %d\n\n", port);
fflush(stdout);
FD_ZERO(&masterList);
FD_ZERO(&readFd);
FD_SET(request_sd, &masterList);
fd_max = request_sd;
while(1){
readFd = masterList;
if((select_client = select(fd_max+1, &readFd, NULL, NULL, NULL)) < 0){
perror("FAILED TO SELECT");
}
for ( i = 0; i <= fd_max; i++)
{
if(FD_ISSET(i,&readFd))
{
if(i == request_sd)
{
newfd = accept(request_sd, (struct sockaddr*) &client_adr,
(socklen_t *) &clientaddrlen);
if (newfd == -1 )
{
perror("failed to accept :");
return -1;
}
FD_SET(newfd, &masterList);
if (newfd > fd_max)
{
fd_max = newfd;
}
答案 0 :(得分:1)
由于select()
抱怨错误的参数,并且您只向其传递了两个参数,这意味着fd_max
无效或readFd
无效。 documentation州:
EINVAL
nfds为负数或超时内包含的值无效。
由于您未使用timeout
参数,请查看您的fd_max
变量,确保您没有溢出。
除此之外,您应该在支持它的平台上使用fd_copy()
而不是readFd = masterList
。
FD_COPY(&masterList, &readFd);
更好的选择是使用poll()
或epoll()
代替select()
。它更易于管理,并且它会告诉您满足等待的确切套接字,因此您不必去寻找它们。