TFTP服务器不发送DATA数据包

时间:2015-04-14 12:10:55

标签: c sockets udp tftp

我写了一个简单的tftp服务器,它只处理来自客户端的读取请求(RRQ)。问题是服务器似乎没有向客户端发送DATA数据包。我确保服务器没有通过检查发送字节长度与数据包大小来发送DATA数据包。

注意:我使用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, '\0', 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;
}

提前致谢:)

1 个答案:

答案 0 :(得分:1)

您的操作码检查似乎不正确。

尝试:

bufindex++;
 opcode = *bufindex++;

另外,为什么在sendto中有1024个字节。不应该是文件的大小?您只是传递packetbuf的大小而不是文件的实际大小。

更改为:

sendto((sock, packetbuf, len, 0, (struct sockaddr *) &client, sizeof (client)) );