⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tftpc.c

📁 tftp-1.0源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    memset (buf, 0, sizeof (buf));    len =        sprintf (buf, "%c%c%c%c%s%c", 0x00, ERR, 0x00, err_code, err_msg, 0x00);    if (len == 0)    {        printf ("Error in creating the ACK packet\n");	/*could not print to the client buffer */        exit (ERROR);    }    if (debug)    {        printf ("I am creating an ERROR packet.\n");    }    return len;}/* A function used for debuging to show the port numbers used*/voidip_port (struct sockaddr_in host){    printf ("The IP port pair for the host is: IP:%s Port:%d \n",            inet_ntoa (host.sin_addr), ntohs (host.sin_port));}/**This function is called when the client would like to upload a file to the server.*/voidtsend (char *pFilename, struct sockaddr_in server, char *pMode, int sock){    int len, server_len, opcode, ssize = 0, n, i, j, bcount = 0, tid;    unsigned short int count = 0, rcount = 0, acked = 0;    unsigned char filebuf[MAXDATASIZE + 1];    unsigned char packetbuf[MAXACKFREQ][MAXDATASIZE + 12],                  recvbuf[MAXDATASIZE + 12];    char filename[128], mode[12], *bufindex;	//fullpath[196],    struct sockaddr_in ack;    FILE *fp;			/* pointer to the file we will be sending */    strcpy (filename, pFilename);	//copy the pointer to the filename into a real array    strcpy (mode, pMode);		//same as above    if (debug)        printf ("Client: branched to file send function\n");    /*At this point I have to wait to recieve an ACK from the server before I start sending the file*/    /*open the file to read */    fp = fopen (filename, "r");    if (fp == NULL)    {				//if the pointer is null then the file can't be opened - Bad perms OR no such file        if (debug)            printf ("Client: sending bad file: file not found (%s)\n", filename);        return;    }    else    {        if (debug)            printf ("Client: Sending file... (source: %s)\n", filename);    }    //get ACK for WRQ    /* The following 'for' loop is used to recieve/timeout ACKs */    for (j = 0; j < RETRIES - 2; j++)    {        server_len = sizeof (ack);        errno = EAGAIN;        n = -1;        for (i = 0; errno == EAGAIN && i <= TIMEOUT && n < 0; i++)        {            n = recvfrom (sock, recvbuf, sizeof (recvbuf), MSG_DONTWAIT,                    (struct sockaddr *) &ack, (socklen_t *) & server_len);            usleep (1000);        }        /* if(debug)           ip_port (ack);    print the vlaue recived from the server */        tid = ntohs (ack.sin_port);	//get the tid of the server.        server.sin_port = htons (tid);	//set the tid for rest of the transfer        if (n < 0 && errno != EAGAIN)        {            if (debug)                printf                    ("Client: could not receive from the server (errno: %d n: %d)\n",                     errno, n);            //resend packet        }        else if (n < 0 && errno == EAGAIN)        {            if (debug)                printf ("Client: Timeout waiting for ack (errno: %d n: %d)\n",                        errno, n);            //resend packet        }        else        {			/*changed client to server here */            if (server.sin_addr.s_addr != ack.sin_addr.s_addr)	/* checks to ensure send to ip is same from ACK IP */            {                if (debug)                    printf                        ("Client: Error recieving ACK (ACK from invalid address)\n");                j--;		/* in this case someone else connected to our port. Ignore this fact and retry getting the ack */                continue;            }            if (tid != ntohs (server.sin_port))	/* checks to ensure get from the correct TID */            {                if (debug)                    printf                        ("Client: Error recieving file (data from invalid tid)\n");                len = err_packet (5, err_msg[5], buf);                if (sendto (sock, buf, len, 0, (struct sockaddr *) &server, sizeof (server)) != len)	/* send the data packet */                {                    printf                        ("Client: Mismatch in number of sent bytes while trying to send mode error packet\n");                }                /* if (debug)                   ip_port(server); */                j--;                continue;		/* we aren't going to let another connection spoil our first connection */            }            /* this formatting code is just like the code in the main function */            bufindex = (char *) recvbuf;	//start our pointer going            if (bufindex++[0] != 0x00)                printf ("Client: bad first nullbyte!\n");            opcode = *bufindex++;            rcount = *bufindex++ << 8;            rcount &= 0xff00;            rcount += (*bufindex++ & 0x00ff);            if (opcode != 4 || rcount != count)	/* ack packet should have code 4 (ack) and should be acking the packet we just sent */            {                if (debug)                    printf                        ("Client: Remote host failed to ACK proper data packet # %d (got OP: %d Block: %d)\n",                         count, opcode, rcount);                /* sending error message */                if (opcode > 5)                {                    len = err_packet (4, err_msg[4], buf);                    if (sendto (sock, buf, len, 0, (struct sockaddr *) &server, sizeof (server)) != len)	/* send the data packet */                    {                        printf                            ("Client: Mismatch in number of sent bytes while trying to send mode error packet\n");                    }                }                /* from here we will loop back and resend */                /* if (debug)                   ip_port(server); */            }            else            {                if (debug)                    printf ("Client: Remote host successfully ACK'd (#%d)\n",                            rcount);                break;            }        }			//end of else        if (debug)            printf ("Client: Ack(s) lost. Resending complete.\n");    }    /* The ack sending 'for' loop ends here */    memset (filebuf, 0, sizeof (filebuf));	//clear the filebuf    while (1)			/* our break statement will escape us when we are done */    {        acked = 0;        ssize = fread (filebuf, 1, datasize, fp);        if (debug)        {            printf                ("The first data block has been read from the file and will be sent to the server\n");            printf ("The size read from the file is: %d\n", ssize);        }        count++;			/* count number of datasize byte portions we read from the file */        if (count == 1)		/* we always look for an ack on the FIRST packet */            bcount = 0;        else if (count == 2)	/* The second packet will always start our counter at zreo. This special case needs to exist to avoid a DBZ when count = 2 - 2 = 0 */            bcount = 0;        else            bcount = (count - 2) % ackfreq;        sprintf ((char *) packetbuf[bcount], "%c%c%c%c", 0x00, 0x03, 0x00, 0x00);	/* build data packet but write out the count as zero */        memcpy ((char *) packetbuf[bcount] + 4, filebuf, ssize);        len = 4 + ssize;        packetbuf[bcount][2] = (count & 0xFF00) >> 8;	//fill in the count (top number first)        packetbuf[bcount][3] = (count & 0x00FF);	//fill in the lower part of the count        if (debug)            printf ("Client: Sending packet # %04d (length: %d file chunk: %d)\n",                    count, len, ssize);        /* send the data packet */        if (sendto                (sock, packetbuf[bcount], len, 0, (struct sockaddr *) &server,                 sizeof (server)) != len)        {            if (debug)                printf ("Client: Mismatch in number of sent bytes\n");            return;        }        if (debug)        {            ip_port (server);            printf ("==count: %d  bcount: %d  ssize: %d  datasize: %d\n", count,                    bcount, ssize, datasize);        }        //if ((count - 1) == 0 || ((count - 1) % ackfreq) == 0 || ssize != datasize)        if (((count) % ackfreq) == 0 || ssize != datasize)        {            if (debug)                printf ("-- I will get an ACK\n");            /* The following 'for' loop is used to recieve/timeout ACKs */            for (j = 0; j < RETRIES; j++)            {                server_len = sizeof (ack);                errno = EAGAIN;                n = -1;                for (i = 0; errno == EAGAIN && i <= TIMEOUT && n < 0; i++)                {                    n =                        recvfrom (sock, recvbuf, sizeof (recvbuf), MSG_DONTWAIT,                                (struct sockaddr *) &ack,                                (socklen_t *) & server_len);                    /* if (debug)                       ip_port(ack); */                    usleep (1000);                }                if (n < 0 && errno != EAGAIN)                {                    if (debug)                        printf                            ("Client: could not receive from the server (errno: %d n: %d)\n",                             errno, n);                    //resend packet                }                else if (n < 0 && errno == EAGAIN)                {                    if (debug)                        printf                            ("Client: Timeout waiting for ack (errno: %d n: %d)\n",                             errno, n);                    //resend packet                }                else                {		/* checks to ensure send to ip is same from ACK IP */                    if (server.sin_addr.s_addr != ack.sin_addr.s_addr)                    {                        if (debug)                            printf                                ("Client: Error recieving ACK (ACK from invalid address)\n");                        /* in this case someone else connected to our port. Ignore this fact and retry getting the ack */                        j--;                        continue;                    }                    if (tid != ntohs (server.sin_port))	/* checks to ensure get from the correct TID */                    {                        if (debug)                            printf                                ("Client: Error recieving file (data from invalid tid)\n");                        len = err_packet (5, err_msg[5], buf);                        /* send the data packet */                        if (sendto                                (sock, buf, len, 0, (struct sockaddr *) &server,                                 sizeof (server)) != len)                        {                            printf                                ("Client: Mismatch in number of sent bytes while trying to send mode error packet\n");                        }                        /*if (debug)                          ip_port(server);  */                        j--;                        continue;	/* we aren't going to let another connection spoil our first connection */                    }                    /* this formatting code is just like the code in the main function */                    bufindex = (char *) recvbuf;	//start our pointer going                    if (bufindex++[0] != 0x00)                        printf ("Client: bad first nullbyte!\n");                    opcode = *bufindex++;                    rcount = *bufindex++ << 8;                    rcount &= 0xff00;                    rcount += (*bufindex++ & 0x00ff);                    if (opcode != 4 || rcount != count)	/* ack packet should have code 4 (ack) and should be acking the packet we just sent */                    {                        if (debug)                            printf                                ("Client: Remote host failed to ACK proper data packet # %d (got OP: %d Block: %d)\n",                                 count, opcode, rcount);                        /* sending error message */                        if (opcode > 5)                        {                            len = err_packet (4, err_msg[4], buf);                            if (sendto (sock, buf, len, 0, (struct sockaddr *) &server, sizeof (server)) != len)	/* send the data packet */                            {                                printf                                    ("Client: Mismatch in number of sent bytes while trying to send mode error packet\n");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -