私は学校のプロジェクト用に単純なFTPサーバーをコーディングしています。ファイル転送に問題があります。TCPソケットがなぜブロックされているのですか?
実際、コマンドPASVが送信されると、指定されたポートでソケットを作成してリッスンしますが、その後、コマンドRETRが送信され、ソケットファイル記述子にファイルを書き込もうとすると、プログラムとftpクライアントの終了を待つ。
はなぜこの書き込みをブロックしていますか?この関数は、私のソケットこの機能オープン広告は、データラインthroughtファイルを送信
void cmd_pasv(t_handle *hdl)
{
struct sockaddr_in data_sock;
uint16_t port;
socklen_t len;
len = sizeof(data_sock);
if ((hdl->data_fd = create_s_socket(&data_sock, 0)) != -1)
{
listen(hdl->data_fd, 5);
getsockname(hdl->data_fd, (struct sockaddr *)&data_sock, &len);
port = ntohs(data_sock.sin_port);
printf("port = %d\n", port);
set_rep(hdl, 227, "Entering Passive Mode (%d,%d,%d,%d,%d,%d).",
(int)(data_sock.sin_addr.s_addr & 0xFF),
(int)((data_sock.sin_addr.s_addr & 0xFF00) >> 8),
(int)((data_sock.sin_addr.s_addr & 0xFF0000) >> 16),
(int)((data_sock.sin_addr.s_addr & 0xFF000000) >> 24),
(int)(port/256), (int)(port % 256));
printf("data fd %d\n", hdl->data_fd);
}
else
set_rep(hdl, 500, "Canno open data connection");
}
int create_s_socket(struct sockaddr_in *sock, int port)
{
int socket_fd;
int enable;
if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
return (-1);
enable = 1;
if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0)
return (-1);
sock->sin_family = AF_INET;
sock->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
sock->sin_port = htons(port);
if (bind(socket_fd, (struct sockaddr *)sock, sizeof(*sock)) < 0)
return (-1);
return (socket_fd);
}
この機能は、オープンデータ接続を開く(パッシブモード)を作成
void cmd_retr(t_handle *hdl)
{
char *fullpath;
FILE *file;
size_t nread;
char buf[BLOCK_SIZE];
log_msg(INFO, "data fd is %d", hdl->data_fd);
if (hdl->data_fd > 0)
{
log_msg(INFO, "data fd is %d", hdl->data_fd);
if (hdl->cmd_arg)
{
log_msg(INFO, "file to uploadis %s", hdl->cmd_arg);
fullpath = malloc(sizeof(char) *
strlen(hdl->path) + strlen(hdl->cmd_arg) + 2);
sprintf(fullpath, "%s/%s", hdl->path, hdl->cmd_arg);
log_msg(INFO, "full path is %s", fullpath);
if ((file = fopen(fullpath, "r")) != NULL)
{
log_msg(INFO, "file opened correctly");
while ((nread = fread(buf, sizeof(char), BLOCK_SIZE, file)) > 0)
{
log_msg(INFO, "read %d bytes \"%s\"", nread, buf);
if (write(hdl->data_fd, buf, nread) == -1)
log_msg(ERROR, "write: %s", strerror(errno));
}
if (nread < 0)
log_msg(ERROR, "read: %s", strerror(errno));
}
else
set_rep(hdl, 000, "File \"%s\" not found", fullpath);
free(fullpath);
}
else
set_rep(hdl, 000, "Missing arg");
}
else
set_rep(hdl, 000, "Data connection not open fd %d", hdl->data_fd);
}
感謝;)
、ときに、クライアントの要求それは作成するには、このprevioulsy格納されているIPとポートの組み合わせを使用したファイルソケットは受け入れてから書き込みますか? –
@ TheChampionの場合、サーバーはまずPASVコマンドを受け入れ、クライアントに適切な応答を送信する必要があります。データ・チャネルは、*セッションごとの*プロパティである、しかし、ないファイル単位または要求財産ので、あなたは、クライアントがデータチャネルを開こうとする前に、新しいコマンドを発行することを期待すべきではない、と確かに開きませんコマンドごとの新しい接続。適切なサーバー側の動作をどのように実装するかは、あなた次第です。この回答のポイントは、接続されているソケットではなくリッスンソケットに書き込もうとすると発生する問題です。 –