尝试让我的简单FTP服务器运行。它在远程服务器上运行。使用cat /etc/*-release
显示服务器正在运行CentOS Linux 7核心。
参考:http://pubs.opengroup.org/onlinepubs/9699919799/,具体来说:
指定使用socket()创建的套接字,已绑定到带有bind()的地址,并已成功调用listen()。
我的程序成功调用socket
,bind
和listen
- 然后accept
在服务器上失败。在OSX 10.11.5上它可以正常工作(在评论几个标题后)。
我正在使用gcc -std=c11 ftserver.c -o ftserver
进行远程编译。使用logging和stderr我从执行中得到以下内容,抛出exit(1)。
记录输出(编辑):
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>
答案 0 :(得分:2)
从您显示的日志中
sockfd = 0
很明显,在listen()
和accept()
的来电之间,FD sockfd
会被覆盖(此处:0
)。
这很可能是因为在某个地方或之前调用了未定义的行为。
后者很可能会将 完全初始化 struct sigaction
传递给sigaction()
。
要解决此问题,请正确初始化struct sigaction
,例如:
struct sigaction signal_action = {0};