我有一个程序应该接受端口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");
}
}
答案 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