基本C服务器:连接拒绝错误

时间:2013-05-01 21:13:58

标签: c sockets networking tcp

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

在OS X 10.8.3下编译时,此代码适用于我,但在Oracle Enterprise Linux上运行时拒绝连接。 accept()永远不会接受连接,并且从另一台设备telnet到端口会出现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");
    }
}

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

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

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