accept()在成功执行socket()、bind()、listen()之后失败,错误号为88 ENOTSOCK
正在尝试运行我的简单FTP服务器。它正在远程服务器上运行。使用accept()在成功执行socket()、bind()、listen()之后失败,错误号为88 ENOTSOCK,c,sockets,network-programming,signals,C,Sockets,Network Programming,Signals,正在尝试运行我的简单FTP服务器。它正在远程服务器上运行。使用cat/etc/*-release显示服务器正在运行CentOS Linux 7 core 引用:,具体是: 指定一个套接字,该套接字是使用socket()创建的,已使用bind()绑定到地址,并已成功调用listen() 我的程序成功地调用了socket、bind和listen——然后accept在服务器上失败。在OSX 10.11.5上,它工作得很好(在注释了几个标题之后) 我正在使用gcc-std=c11 ftserver.c-
cat/etc/*-release
显示服务器正在运行CentOS Linux 7 core
引用:,具体是:
指定一个套接字,该套接字是使用socket()创建的,已使用bind()绑定到地址,并已成功调用listen()
我的程序成功地调用了socket
、bind
和listen
——然后accept
在服务器上失败。在OSX 10.11.5上,它工作得很好(在注释了几个标题之后)
我正在使用gcc-std=c11 ftserver.c-o ftserver
进行远程编译。通过使用日志记录和stderr,我从执行到抛出退出(1)得到以下信息
日志输出(编辑):
ftserver 30000来自您显示的日志
sockfd=0
很明显,在调用listen()
和accept()
之间,FDsockfd
会被覆盖(此处:to0
)
这很可能是由于未定义的行为在当时或之前被调用
后者很可能是由于将一个未完全初始化的struct sigaction
传递到sigaction()
要解决此问题,请正确初始化struct sigaction
,例如:
struct sigaction signal_action = {0};
Errno 88通常表示非套接字上的套接字操作。请在每次操作后打印sockfd值,并再次检查您是否在其他地方对其进行了干预。if(bind(sockfd,(struct sockaddr*)&addr\u client,sizeof(struct sockaddr))==-1)
我认为应该是sizeof sockaddr\u in
或sizeof addr\u client
所以有人在将套接字FD归零。尝试注释sigaction内容。struct sigaction signal\u action代码>未正确初始化。Dostruct sigaction signal_action={0}代码>并重新测试。@FearJoy我并不是说它能解决问题。不过你还是应该通过正确的尺寸。
int main (int argc, char *argv[]) {
if (argc != 2) {
printf("Usage: ftserver <port number>\n");
exit(1);
}
int port = atoi(argv[1]);
char client_hostname[STRING_LENGTH];
bzero(client_hostname, STRING_LENGTH);
// set up the server's socket
int sockfd;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ) {
fprintf(stderr, "[ ERROR ] :: main() :: Failure to assign sockfd");
exit(1);
}
else {
printf("socket() succeeded with sockfd = %d\n", sockfd);
}
// fill the client socket address struct
struct sockaddr_in addr_client;
addr_client.sin_family = AF_INET;
addr_client.sin_port = htons(port);
addr_client.sin_addr.s_addr = INADDR_ANY;
bzero(&(addr_client.sin_zero), 8);
if (bind(sockfd, (struct sockaddr*)&addr_client, sizeof(struct sockaddr)) == -1 ) {
fprintf(stderr, "[ ERROR ] :: main() :: Failure to bind port %d. Please select another port\n", port);
exit(1);
}
else {
printf("bind() succeeded with sockfd = %d\n", sockfd);
}
if (listen(sockfd, QUEUE) == -1) {
fprintf(stderr, "[ ERROR ] :: main() :: Failure to listen on port %d\n", port);
exit(1);
}
else {
printf("listen() succeeded with sockfd = %d\n", sockfd);
}
printf ("Server open on %d\n", port);
struct sigaction signal_action;
signal_action.sa_handler = kill_zombies;
sigemptyset(&signal_action.sa_mask);
signal_action.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &signal_action, NULL) == -1) {
perror("sigaction");
return 1;
}
else {
printf("sigaction succeeded\n");
}
struct sockaddr_in addr_server;
int temp_sockfd;
while (1) {
socklen_t sin_size = sizeof(struct sockaddr_in);
// accept() is used to connection to a client
if ((temp_sockfd = accept(sockfd, (struct sockaddr *)&addr_server, &sin_size)) == -1) {
fprintf(stderr, "ERROR: Obtaining new socket descriptor with \n\tsockfd = %d\n\ttemp_sockfd = %d\n\terrno = %d\n", sockfd, temp_sockfd, errno);
exit(1);
}
else {
printf("accept() succeeded\n");
}
// more code that we never have the pleasure to exec
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <strings.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <signal.h>
// includes for server (CentOS) errors
// comment these out to compile locally (OSX)
// fixes error: ‘WNOHANG’ undeclared
#include <sys/wait.h>
// fixes error: ‘SA_RESTART’ undeclared
#include <asm/signal.h>
struct sigaction signal_action = {0};