gpt4 book ai didi

c - 被动套接字不接受 ftp

转载 作者:行者123 更新时间:2023-11-30 15:58:04 26 4
gpt4 key购买 nike

我正在创建一个 ftp 服务器,当我尝试使用 filezilla 连接到它时,服务器不接受被动套接字上的连接。它在接受调用时挂起。这是我的代码的一部分:

if ((服务器->pasv_sock = 接受(服务器->sockt, (struct sockaddr*)&sin_clt,
(socklen_t*)&size_sin) == -1))

我的套接字绑定(bind)到特定端口,客户端尝试与该端口连接。 Telnet 也未连接。

如果你能帮我找出问题所在,谢谢:)

最佳答案

您是否记得在accept之前调用listen

记住:socket -> bind -> listen -> accept

编辑:这是对您的代码的一些注释。

  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 流协议(protocol)。使用 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)

但我不建议这样做。更容易阅读并且更万无一失的是从 if 谓词中提取赋值,

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 条件或 while 条件中进行最终比较。

// 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)
...

关于c - 被动套接字不接受 ftp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10059523/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com