Попытка получить мой простой FTP-сервер. Он работает на удаленном сервере. Использование cat /etc/*-release
показывает, что на сервере работает ядро CentOS Linux 7.accept() сбой после успешного сокета(), bind(), listen() с errno 88 ENOTSOCK
Реферировано: http://pubs.opengroup.org/onlinepubs/9699919799/, а именно:
Определяет сокет, который был создан с гнездом(), был связан с адресом с Bind(), и выпустил успешный вызов слушать().
Моя программа успешно называет socket
, bind
и listen
- тогда accept
сбой на сервере. В OSX 10.11.5 он работает очень хорошо (после комментирования нескольких заголовков).
Я собираюсь удаленно с gcc -std=c11 ftserver.c -o ftserver
. Используя logging и stderr, я получаю следующее от выполнения, чтобы он выбрал exit (1).
выход Logging (редактировать):
ftserver 30000 <-- start the server on port 30000
socket() succeeded with sockfd = 3
bind() succeeded with sockfd = 3
listen() succeeded with sockfd = 3
Server open on 30000
ERROR: Obtaining new socket descriptor with
sockfd = 0
temp_sockfd = -1
errno = 88
Вот код с точки программы ввода в строку, которая бросает ошибку.
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>
Errno 88 обычно указывает на работу сокетов о неприменении розеткой. Pls печатает значения sockfd после каждой операции, а также дважды проверяет, не мешаете ли вы с ним в другом месте. – Jay
'if (bind (sockfd, (struct sockaddr *) & addr_client, sizeof (struct sockaddr)) == -1)' Я думаю, что это должно быть 'sizeof sockaddr_in' или' sizeof addr_client' –
@Jay - я обновил свой должность в двух местах. Один из них - это вывод журнала с указанными значениями 'sockfd'. Второй - это код, который делает вывод (согласованность eh?). Вышеупомянутый код является точкой входа в программу, ничего не вызывается или не выполняется до того, что я опубликовал. – FearJoy