3

我有一个程序应该接受端口 62085 的连接并发回测试消息。代码在 accept() 处挂起,即使客户端尝试连接也不会返回。为什么服务器拒绝连接?会不会是防火墙问题?

此代码在 OS X 10.8.3 下编译时适用于我,但在 Oracle Enterprise Linux 上运行时拒绝连接。 accept()永远不会接受连接,并且从另一台设备远程登录到该端口会Connection Refused出错。下面是 netstat 的输出,证明程序实际上正在监听我想要的端口。我尝试了其他端口,62084、666 和 8080,看看是否有东西阻塞了那个特定的端口。(netstat 输出来自两个不同的命令)。

   tcp        0      0 0.0.0.0:62085               0.0.0.0:*                   LISTEN      11815/del-chef  

   tcp        0      0 129.133.124.83:62085        0.0.0.0:*                   LISTEN      15101/del-chef  

iptables 显示它也允许所有端口上的连接。

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED 
ACCEPT     icmp --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ssh 
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:http 
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:https 
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:yo-main 
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:terabase 
REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited 

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited 

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination`

的输出sudo iptables -t mangle -L

该命令的输出是

Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         

OS X 设备和 Enterprise Linux Server 都在同一个网络上运行,所以我很困惑为什么执行时telnet XXX.XXX.XXX.XXX 62085会收到Connection Refused错误消息。

相关代码如下:

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netdb.h>
#include <fcntl.h>
#include <syslog.h>
#include <signal.h>

#define BACKLOG 10
#define PORT "62085"

void main() {
    struct sockaddr_in cli_addr;
    socklen_t addr_size;
    struct addrinfo hints, *res, *p;
    int sockfd, new_fd;
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_INET;  // use IPv4
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;     // fill in my IP for me

    if (getaddrinfo(NULL, PORT, &hints, &res) != 0){
        syslog(LOG_ERR, "getaddrinfo() error");
        exit(1);
    }
    for (p = res; p != NULL; p = p->ai_next){
        if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1){
            syslog(LOG_ERR, "Error creating socket");
            continue;
        }
        int yes = 1;
        if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1){
            syslog(LOG_ERR, "Error settings socket options");
            exit(1);
        }
        if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1){
            close(sockfd);
            syslog(LOG_ERR, "Error binding socket");
            continue;
        }

        break;    
    }
    if (p == NULL){
        close(sockfd);
        syslog(LOG_ERR, "Error binding socket");
        exit(1);
    }
    freeaddrinfo(res); // free memory now that it is no longer in use

    if (listen(sockfd, BACKLOG) == -1){
        close(sockfd);
        syslog(LOG_ERR, "Error listening");
        exit(1);
    }
    syslog(LOG_INFO, "Waiting for connections");
    addr_size = sizeof(cli_addr);
    if (new_fd = accept(sockfd, (struct sockaddr *)&cli_addr, &addr_size) == -1){
        syslog(LOG_ERR, "Error accepting connection");
    }
}
4

2 回答 2

2

您显示的代码没有任何问题,因此问题出在您的应用程序之外。由于您的套接字显然正在侦听并且尚未耗尽其积压,因此连接被拒绝错误必须意味着操作系统本身,或者可能/可能是防火墙/路由器,在连接到达您的应用程序之前拒绝连接。

于 2013-05-02T08:33:36.407 回答
0

原来是 iptables,发布service stop iptables允许代码工作。我最终将以下规则添加到 iptables:

sudo iptables -I INPUT 5 -m state --state NEW -m tcp -p tcp --dport 62085 -j ACCEPT

于 2013-05-02T18:18:42.153 回答