2012-04-08 61 views
0

我正在做一个ftp服务器,当我试图用filezilla连接到它时,服务器不接受被动套接字上的连接。它挂在接受电话。 这里是我的代码的一部分:被动套接字不接受ftp

if ((server->pasv_sock = accept(server->sockt, (struct sockaddr*)&sin_clt, (socklen_t*)&size_sin) == -1))

我的插座绑定到特定的端口和客户端试图与这一个连接。 Telnet也没有连接。

如果你能帮助我找到了什么问题,谢谢:)

回答

1

你记得accept之前调用listen

切记:socketbindlistenaccept

编辑:下面是您的代码的一些评论。

struct protoent  *pe; 
    struct sockaddr_in sin; 
    int     sock; 
    struct sockaddr_in sin_clt; 
    int     size_sin; 

    if ((pe = getprotobyname("TCP")) == NULL) 
     perro("getprotobyname"); 
    sock = xsocket(AF_INET, SOCK_STREAM, pe->p_proto); 

使用getprotobyname是不必要的,因为名字是硬编码的,只有一个IP流协议反正。使用0而不是pe->p_proto,并且不要打电话getprotobyname

sin.sin_family = AF_INET; 
    sin.sin_addr.s_addr = INADDR_ANY; 

您不初始化sin.sin_port。这是一个错误。

while (bind(sock, (const struct sockaddr*)&sin, 
       (socklen_t)sizeof(sin)) == -1 && server->port2 <= 65535) 
    sin.sin_port = htons(server->port2++); 

这个循环有点乱。这可能大部分是正确的,但很难说清楚。让我们重写它,所以它的显然是正确的而不是明显不正确

if (listen(sock, 1) == -1) 
    perror("listen"); 
    size_sin = sizeof(sin_clt); 
    if ((server->pasv_sock = accept(sock, (struct sockaddr*)&sin_clt, 
            (socklen_t*)&size_sin) == -1)) 

这绝对不会做你想要的。

讨论:我会加括号的最后一行向你展示它实际上做什么。

if ((server->pasv_sock = accept(...) == -1)) 

相同

if ((server->pasv_sock = (accept(...) == -1))) 

我猜你明白我的抱怨分配,这表明加括号编译器警告...但你加括号是错误的地点。编译器警告你的原因是因为这是一个常见的错误来源,编译器不可能知道你实际上该语句的含义。你的意思是更类似于:

if ((server->pasv_sock = accept(...)) == -1) 

但我不建议这样做。更易于阅读和更防呆是拉出来的任务,如果谓词,

server->pasv_sock = accept(...); 
if (server->pasv_sock == -1) 

而且没有,有在生成汇编代码没有什么区别;所以没有性能差异。

这条线还有另一个问题,但它有点迂腐。你不应该铸造(socklen_t *) &size_sin。相反,您应该将size_sin的声明更改为以socklen_t类型开头。它工作的唯一原因是因为socklen_t键入的值为int,但假装你不知道并使用正确的类型开始。

示例代码:

int port, sock, r, csock; 
struct sockaddr_in saddr, caddr; 
socklen_t caddrlen; 

// This is a simpler way to get a TCP socket 
sock = socket(AF_INET, SOCK_STREAM, 0); 
if (sock < 0) abort(); 

// Loop over available ports, and bind to one 
// (I'm not sure if this is the best way to do this) 
saddr.sin_family = AF_INET; 
saddr.sin_addr.s_addr = INADDR_ANY; 
for (port = 10000; port < 65536; ++port) { 
    saddr.sin_port = htons(port); 
    r = bind(sock, (struct sockaddr *) &saddr, (socklen_t) sizeof(saddr)); 
    if (!r) 
     break; 
} 
if (r) abort(); 

// Listen and accept a connection 
r = listen(sock, 1); 
if (r < 0) abort(); 
caddrlen = (socklen_t) sizeof(caddr); 
csock = accept(sock, (struct sockaddr *) &caddr, &caddrlen); 
if (csock < 0) abort(); 

// You don't want to listen for more connections 
close(sock); 

建议步骤:现在,尝试从把副作用(acceptbind,分配等)的条件语句望而却步。我并不是说这样做永远不会好,但看起来就像是你的问题所在,并且将副作用移动到单独的代码行非常容易,那么只有在if中做最后的比较条件或条件。

// Both of these are correct. 
// The bottom one is obviously correct. 
// Correctness is not always good enough. 
// Being obviously correct is important! 

if ((p->x = func()) == NULL) 
    ... 

p->x = func(); 
if (p->x == NULL) 
    ... 
+0

是的,我听了1个连接,我也尝试了更多。我的模式很好。 – 2012-04-08 00:54:47

+0

在这种情况下,您需要向我们展示更多代码。 – 2012-04-08 00:55:56

+0

好的,感谢您的帮助,这里是:http://pastebin.com/nJQdZGJf – 2012-04-08 01:00:17