TFTP 服务器不发送数据包
TFTP Server Is Not Sending DATA packets
我编写了一个简单的 tftp 服务器,它只处理来自客户端的读取请求 (RRQ)。问题是服务器似乎没有向客户端发送数据包。我通过检查发送字节的长度与数据包大小来确保服务器没有发送数据包。
注意:我使用 linux 附带的标准 tftp 客户端。
这是我到目前为止编写的代码...
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
void sendFile (char *Filename, char *mode, struct sockaddr_in client)
{
char path[70] = "tmp/";
char filebuf [1024];
int acked = 0; // Number of acked data portions
int count = 0; // Number of data portions we sent
unsigned char packetbuf[1024];
char recvbuf[1024];
socklen_t recv_size;
int sock = socket(PF_INET, SOCK_DGRAM, 0);
FILE *fp;
char fullpath[200];
strcpy(fullpath, path);
strncat(fullpath, Filename, sizeof(fullpath) -1);
fp = fopen(fullpath, "r");
if (fp == NULL)
perror("");
memset(filebuf, 0, sizeof(filebuf));
while (1)
{
int ssize = fread(filebuf, 1 , 512, fp);
count++;
sprintf((char *) packetbuf, "%c%c%c%c", 0x00, 0x03, 0x00, 0x00);
memcpy((char *) packetbuf + 4, filebuf, ssize);
packetbuf[2] = (count & 0xFF00) >> 8;
packetbuf[3] = (count & 0x00FF);
int len = 4 + ssize;
if (sendto(sock, packetbuf, len, 0, (struct sockaddr *) &client, sizeof(client)) != len)
puts("SENDING FAILED!");
memset(recvbuf, 0, 1024);
recvfrom(sock, recvbuf, 1024, 0, (struct sockaddr *) &client, &recv_size);
if (recvbuf[1] == 4)
puts("Acked");
if (ssize != 512)
break;
}
}
int main()
{
int udpSocket, nBytes;
char buffer[1024], filename[200], mode[20], *bufindex, opcode;
struct sockaddr_in serverAddr, client;
struct sockaddr_storage serverStorage;
socklen_t addr_size;
udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(69);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
memset(serverAddr.sin_zero, '[=10=]', sizeof serverAddr.sin_zero);
bind(udpSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));
memset(buffer,0,1024);
while(1)
{
nBytes = recvfrom(udpSocket,buffer,1024,0,(struct sockaddr *)&client, &addr_size);
bufindex = buffer;
bufindex++;
// Extracting the opcode from the packet...
opcode = *bufindex++;
// Extracting the filename from the packet...
strncpy(filename, bufindex, sizeof(filename)-1);
bufindex += strlen(filename) + 1;
// Extracting the mode from the packet...
strncpy(mode, bufindex, sizeof(mode)-1);
// If we received an RRQ...
if (opcode == 1)
sendFile(filename, mode, client);
}
return 0;
}
提前致谢:)
您的操作码检查似乎不正确。
尝试:
bufindex++;
opcode = *bufindex++;
此外,为什么 sendto
中有 1024 个字节。它不应该是文件的大小吗?您只是传递 packetbuf 的大小而不是文件的实际大小。
更改为:
sendto((sock, packetbuf, len, 0, (struct sockaddr *) &client, sizeof (client)) );
我编写了一个简单的 tftp 服务器,它只处理来自客户端的读取请求 (RRQ)。问题是服务器似乎没有向客户端发送数据包。我通过检查发送字节的长度与数据包大小来确保服务器没有发送数据包。
注意:我使用 linux 附带的标准 tftp 客户端。
这是我到目前为止编写的代码...
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
void sendFile (char *Filename, char *mode, struct sockaddr_in client)
{
char path[70] = "tmp/";
char filebuf [1024];
int acked = 0; // Number of acked data portions
int count = 0; // Number of data portions we sent
unsigned char packetbuf[1024];
char recvbuf[1024];
socklen_t recv_size;
int sock = socket(PF_INET, SOCK_DGRAM, 0);
FILE *fp;
char fullpath[200];
strcpy(fullpath, path);
strncat(fullpath, Filename, sizeof(fullpath) -1);
fp = fopen(fullpath, "r");
if (fp == NULL)
perror("");
memset(filebuf, 0, sizeof(filebuf));
while (1)
{
int ssize = fread(filebuf, 1 , 512, fp);
count++;
sprintf((char *) packetbuf, "%c%c%c%c", 0x00, 0x03, 0x00, 0x00);
memcpy((char *) packetbuf + 4, filebuf, ssize);
packetbuf[2] = (count & 0xFF00) >> 8;
packetbuf[3] = (count & 0x00FF);
int len = 4 + ssize;
if (sendto(sock, packetbuf, len, 0, (struct sockaddr *) &client, sizeof(client)) != len)
puts("SENDING FAILED!");
memset(recvbuf, 0, 1024);
recvfrom(sock, recvbuf, 1024, 0, (struct sockaddr *) &client, &recv_size);
if (recvbuf[1] == 4)
puts("Acked");
if (ssize != 512)
break;
}
}
int main()
{
int udpSocket, nBytes;
char buffer[1024], filename[200], mode[20], *bufindex, opcode;
struct sockaddr_in serverAddr, client;
struct sockaddr_storage serverStorage;
socklen_t addr_size;
udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(69);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
memset(serverAddr.sin_zero, '[=10=]', sizeof serverAddr.sin_zero);
bind(udpSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));
memset(buffer,0,1024);
while(1)
{
nBytes = recvfrom(udpSocket,buffer,1024,0,(struct sockaddr *)&client, &addr_size);
bufindex = buffer;
bufindex++;
// Extracting the opcode from the packet...
opcode = *bufindex++;
// Extracting the filename from the packet...
strncpy(filename, bufindex, sizeof(filename)-1);
bufindex += strlen(filename) + 1;
// Extracting the mode from the packet...
strncpy(mode, bufindex, sizeof(mode)-1);
// If we received an RRQ...
if (opcode == 1)
sendFile(filename, mode, client);
}
return 0;
}
提前致谢:)
您的操作码检查似乎不正确。
尝试:
bufindex++;
opcode = *bufindex++;
此外,为什么 sendto
中有 1024 个字节。它不应该是文件的大小吗?您只是传递 packetbuf 的大小而不是文件的实际大小。
更改为:
sendto((sock, packetbuf, len, 0, (struct sockaddr *) &client, sizeof (client)) );