2016-10-13 15 views
0

我试图制作一个接受连接的非常简单的服务器。sockaddr.sin_port = 1337与“真实”打开的端口不匹配

int sock, serv; 
struct sockaddr_in in_sock; 
serv = socket(AF_INET, SOCK_STREAM, 0); 
in_sock.sin_addr.s_addr = 0; 
in_sock.sin_port = 1337; 
in_sock.sin_family = AF_INET; 
bind(serv, (struct sockaddr *)&in_sock, sizeof(in_sock)); 
listen(serv, 0); 
client = accept(serv, 0, 0); 

但是尝试连接到127.0.0.1:1337的时候,我得到一个连接被拒绝的消息:

(未知)[127.0.0.1] 1337(?):连接被拒绝

然而一个简单的netstat -tcpan让我发现,一个端口被打开确实:

TCP 0 0 0.0.0.0: 14597 0.0.0.0:* LISTEN

如果我将sin_port设置为更高的端口,它似乎可以正常工作。

缺少什么我在这里?为什么不打开1337端口?它似乎也是免费的。

+0

你必须使用['htons'(https://linux.die.net/man/3/htons)的端口连接到交换机的字节顺序 –

回答

3

struct sockaddr_in中的端口号字段以网络字节顺序存储。这意味着存储的值,就当你必须使用htons()

in_sock.sin_port = htons(1337); 

否则,端口号将保留字节交换。这正是这里发生了:

1337 = 0x0539 
14597 = 0x3905 
+0

这很有趣,我认为这可能是问题,我应该更深入地研究它。非常感谢,这是问题所在。 – user96649

1
listen(serv, 0); 

的第二个参数是listenbacklog如果我们看一下documentation for listen

积压参数定义的最大长度,其用于的sockfd 未决的连接队列可以生长。如果连接请求 在队列满时到达,则客户端可能会收到错误 指示ECONNREFUSED,或者如果基础协议支持 重新传输,则该请求可能会被忽略,以便稍后在连接中重新尝试 成功。

ECONNREFUSED正是您收到的错误消息,因为积压已满(它可以保持0个连接,因此它总是已满)。 您应该将该数字增加到至少1,但更高的数字可能会更好listen(serv, 10);

+0

好,但是为什么我可以连接到netstat显示的端口?因此,端口在正确的地址打开,向我发送ECONNREFUSED,但另一个在错误的端口打开,但我可以连接到它? – user96649