gpt4 book ai didi

linux - 第一次在 TFTP 客户端成功完成 GET/PUT 操作后,第二次 TFTP PUT 操作不起作用

转载 作者:太空宇宙 更新时间:2023-11-04 12:36:30 24 4
gpt4 key购买 nike

通过 UDP 套接字实现 TFTP 客户端。首先,我创建 UDP 非阻塞套接字并执行 PUT/GET 操作,它工作正常。但是,当我再次尝试执行 GET/PUT 时,它不起作用。 RRQ/WRQ 请求本身未到达服务器,但已从客户端成功发送。下面是我的 tftp 客户端代码。

============================================= ==========

int sockfd;
struct sockaddr_in serv_addr;


//called when we retrieve a file from the server
void getFile(int port, char *filename)
{
printf("enter to get file\n");
FILE * file;

if (strchr(filename,'/') != NULL )
{
printf("We do not support file transfer out of the current working directory\n");
return;
}

file = fopen(filename, "wb");

if(file == NULL)
{
perror(filename);
return;
}

if(sockfd < 0)
{
printf("Couldn't open socket\n");
return;
}

if(!send_RRQ(sockfd, (struct sockaddr *) &serv_addr, filename, TFTP_SUPORTED_MODE))
{
printf("Error: couldn't send RRQ\n");
return;
}
if(!recvFile(sockfd, (struct sockaddr *) &serv_addr, file,filename))
{
printf("Error: didn't receive file\n");
return;
}
fclose(file);
return;
}


//used to upload files to the server
void putFile(int port, char *filename)
{
printf("filenemae is: %s \t",filename);

PACKET packet;
int result;
FILE * fileh;
int timeout_counter = 0;

if (strchr(filename,'/') != NULL )
{
printf("We do not support file transfer out of the current working directory\n");
return;
}


fileh = fopen(filename, "rb");

if(fileh == NULL)
{
perror(filename);
return;
}

if(!send_WRQ(sockfd, (struct sockaddr *) &serv_addr, filename, TFTP_SUPORTED_MODE))
{
printf("Error: couldn't send WRQ to server\n");
return;
}

while (timeout_counter < MAX_TFTP_TIMEOUTS)
{
result = waitForPacket(sockfd, (struct sockaddr *) &serv_addr, TFTP_OPTCODE_ACK, &packet);
if (result < 0)
{
printf("Error: Timeout sending packet to server\n");
if(!send_WRQ(sockfd, (struct sockaddr *) &serv_addr, filename, TFTP_SUPORTED_MODE))
{
printf("Error: couldn't send WRQ to server\n");
return;
}
timeout_counter++;
}else
{
break;
}
}
if (result < 0)
{
//we still timed out
printf("Timed out after %d tries, is the server running\n",MAX_TFTP_TIMEOUTS);
fclose(fileh);
return;
}
if (packet.optcode == TFTP_OPTCODE_ERR)
{
//we recieved an error, print it
printError(&packet);
}else
{
if (!sendFile(sockfd, (struct sockaddr *) &serv_addr, fileh))
{
printf("Unable to send file to server\n");
}
}
fclose(fileh);
return;
}

int createUDPSocketAndBind(int port)
{
//create a socket
sockfd = socket(PF_INET, SOCK_DGRAM, 0);

//return -1 on error
if (sockfd == -1)
{
return -1;
}

//zero out the struct
bzero((char*) &serv_addr, sizeof(serv_addr));

serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
serv_addr.sin_port = htons(port);

return 0;
}


//main client, checks for args and starts an operation if no errors detected
int main(int argc, char *argv[])
{
int port = 59;
int argOffset = 1;
char* filename;
char fme[] = "test.txt";

createUDPSocketAndBind(port);

printf("for put file\n");
putFile(port,fme); //=====> this operation is successful.


//createUDPSocketAndBind(port); //=====> If I uncomment this function, next operation works.

printf("for getfile\n");
getFile(port,fme); //=======> It is failing.

printf("Usage: %s [-p port] (-w putfile || -r getFile)\n",argv[0]);
}

=========================================================================

最佳答案

我进行了更多调查,发现我的代码和解决方案也存在问题。

当您向服务器发送第一个 RD/WR 请求时,它会创建一个单独的进程或线程来处理您的请求,同时它会创建新的套接字并使用不同的端口号来处理请求RD/WR 请求。

当您使用以下 UDP 套接字 API 从服务器接收响应时,客户端。

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, 结构 sockaddr *src_addr, socklen_t *addrlen);

在“struct sockaddr *src_addr”实例中,端口号将随着服务器使用不同的端口号进行响应而更新已创建以处理您的请求,您的 RD/WR 操作将使用此端口号成功完成。

一旦 RD/WR 成功完成,服务器将关闭为处理您的请求而创建的套接字并开始监听您的新请求在原始端口上。但客户端“struct sockaddr *src_addr”实例仍将具有修改后的端口号,当您尝试发送新的 RD/WR 请求时,它不会到达服务器。这就是第二个 RD/WR 请求不会到达服务器并且会失败的原因。

要在客户端的“struct sockaddr *src_addr”实例中修复此问题,您必须将端口重置为初始值,该值最初用于配置“struct sockaddr *src_addr”的服务器实例。所以在每次 RD/WR 操作后你必须重新设置端口号为原始值。

我对 UDP 套接字很陌生,这对我来说是很好的学习。我认为这对像我这样的初学者会有帮助。

谢谢

关于linux - 第一次在 TFTP 客户端成功完成 GET/PUT 操作后,第二次 TFTP PUT 操作不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41570302/

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