Exemplo n.º 1
0
void handle_alarm(int ignored)
{
    //printf("enter alarm handler\n");
    if(bindFlag == 0)
        return;
    if(preNum != newestNum)
        sendDataAck(sock, &clntAddr);
    preNum = newestNum;
    ualarm(RTT,0);
    return;
}
Exemplo n.º 2
0
Arquivo: cl1.c Projeto: Yeir/TFTP
int tftpread(char *filename) {
	struct sockaddr_in peeraddr;
	memset(&peeraddr, 0 ,sizeof(peeraddr));
	FILE *fp = fopen(filename, "wb");
	if(fp == NULL){
		perror("fopen()");
		return 1;
	}
	while(1) {
		int bufferlen = 0;
		while(bufferlen == 0)	// wait for data
		{
			ioctl(sockfd, FIONREAD, &bufferlen);
		}
		printf("DBG: bufferlen = %d\n", bufferlen);

		void *buffer = malloc(bufferlen);

		int recvLen = sizeof(peeraddr);
		int recvlen = recvfrom(sockfd, buffer, bufferlen, 0, 
							(struct sockaddr *)&peeraddr, &recvLen);
		if(recvlen < 0) {
			perror("recvfrom()");
			break;
		}
		struct TFTPData *d;
		d = (struct TFTPData *)buffer;
		if(d->header.opcode == htons(3)) {
			fwrite(&(d->data), recvlen, 1, fp);
		}
		int y = sendDataAck(&peeraddr, d);
		if(recvlen < 516) {
			close(sockfd);
			break;
		}
	}
	close(fp);
	close(sockfd);
}
Exemplo n.º 3
0
int main(int argc, char *argv[])
{
    /* server var */
    unsigned short servPort;     /* Server port */
    struct sockaddr_in servAddr; /* Local address */

    uint8_t bindMsgSize;

    /* addr&port bind with */
    unsigned long bindIP;
    unsigned short bindPort;


    /* client var */
    unsigned int cliAddrLen;     /* Length of incoming message */
    int recvMsgSize;             /* Size of received message */

    /* packets var */
    uint8_t msgType;
    uint8_t code;

    /*init the Queue used for receive history*/
    mylog = (QUEUE *)malloc(sizeof(QUEUE));
    initQueue(mylog);
    //mylog->qBase = (struct logEntry **)malloc(sizeof(struct logEntry *)*MAXN);
    //mylog->front = mylog->rear = 0;

    /*init loss Record*/
    lossRecord = (node_t *)malloc(sizeof(node_t));

    /*init entry*/
    entry = (struct logEntry *)malloc(sizeof(struct logEntry));
    entry->packet = (struct data_t*)malloc(sizeof(struct data_t));

    /* Check for correct number of parameters */ 
    if (argc >= 2)
    {
        servPort = atoi(argv[1]); /* local port */
        //printf("%s",argv[1] );
    }
    else
    {
        fprintf(stderr,"Usage:  %s <TFRC SERVER PORT>\n", argv[0]);
        exit(1);
    }

    /* bind SIGINT function */
    signal(SIGINT, sigHandler);
    signal(SIGALRM, handle_alarm);

    /* Create socket for sending/receiving datagrams */
    if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
    {
        printf("Failure on socket call, errno:%d\n", errno);
    }

    /* Construct local address structure */
    memset(&servAddr, 0, sizeof(servAddr));     /* Zero out structure */
    servAddr.sin_family = AF_INET;              /* Internet address family */
    servAddr.sin_addr.s_addr = htonl(INADDR_ANY);/* Any incoming interface */
    servAddr.sin_port = htons(servPort);        /* Local port */

    /* create buffer to store packets. 1600 maximum of packet size */
    buffer = (struct control_t*)calloc((size_t)MAX_BUFFER, 1);
    ok = (struct control_t*)calloc((size_t)MAX_BUFFER, 1);
    dataAck = (struct ACK_t*)calloc((size_t)MAX_BUFFER, 1);


    /* Bind to the local address */
    if (bind(sock, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
    {
        printf("Failure on bind, errno:%d\n", errno);
    }

    /* Forever Loop */
    for (;;) 
    {
        cliAddrLen = sizeof(clntAddr);
        //printf(" success!!\n");
        /* Block until receive message from a client */
        if ((recvMsgSize = recvfrom(sock, buffer, MAX_BUFFER, 0, (struct sockaddr *) &clntAddr, &cliAddrLen)) < 0)
        {
            printf("Failure on recvfrom, client: %s, errno:%d\n", inet_ntoa(clntAddr.sin_addr), errno);
            continue;
        }

        buffer->msgLength = ntohs(buffer->msgLength);
        buffer->CxID = ntohl(buffer->CxID);
        buffer->seqNum = ntohl(buffer->seqNum);
        if(buffer->seqNum > seqMax)
            seqMax = buffer->seqNum;

        /* Parsing the packet */
        msgType = buffer -> msgType;
        code = buffer -> code;
        switch (msgType) 
        {
            case CONTROL : 
                {
                    switch (code)
                    {
                        case START :
                            {
                                printf("\nreceived START!!\n\n");
                                if (bindFlag == 0)
                                {
                                    bindFlag = 1;
                                    //init the record var
                                    countRecv = 0;
                                    countRecvBytes = recvMsgSize;
                                    seqMax = buffer->seqNum;
                                    seqMin = buffer->seqNum;

                                    bindPort = clntAddr.sin_port;
                                    bindIP = clntAddr.sin_addr.s_addr;
                                    CxID = buffer->CxID;
                                    bindMsgSize = ntohs(buffer->msgSize);
                                    printf("start packet:\n");
                                    printf("length:%d\n", buffer->msgLength);
                                    printf("type:%d\n", (int)buffer->msgType);
                                    printf("code:%d\n", (int)buffer->code);
                                    printf("Cxid:%d\n", buffer->CxID);
                                    printf("Seq#:%d\n", buffer->seqNum);
                                    printf("size:%d\n\n", buffer->msgSize);
                                    sendOk(sock, &clntAddr, 
                                            buffer->seqNum,
                                            buffer->msgSize
                                          );
                                }
                                break;
                            }
                        case STOP :
                            {
                                if (bindFlag == 1 
                                        && bindIP == clntAddr.sin_addr.s_addr
                                        && bindPort == clntAddr.sin_port)
                                {
                                    printf("\nSTOP msg received!\n\n");
                                    sendOk(sock, &clntAddr, 
                                            buffer->seqNum,
                                            buffer->msgSize
                                          );
                                    printf("\nSTOP OK send!\n\n");
                                    //display the output information
                                    display();
                                    ualarm(0,0);
    mylog = (QUEUE *)malloc(sizeof(QUEUE));
    initQueue(mylog);
    lossRecord = (node_t *)malloc(sizeof(node_t));
                                    bindFlag = 0;

                                }
                                break;
                            }
                        default : break;
                    }

                    break;
                }
            case DATA :
                {
                    //printf("received DATA!!\n");
                    if (bindFlag == 1 
                            && bindIP == clntAddr.sin_addr.s_addr
                            && bindPort == clntAddr.sin_port)
                    {
    //printf("The total packet loss : %lf\n",countDroped);
        countRecv++;
        countRecvBytes += recvMsgSize;
                        data = (struct data_t *)buffer;
                        data->RTT = ntohl(data->RTT);
                        newestNum = data->seqNum;
                       // printf("timeStamp recv%" PRIu64 "\n",data->timeStamp);
                        //printf("timeStamp %lu, %d, %d, %d\n",data->timeStamp, data->seqNum, data->RTT, data->msgLength);
                       
                        if (RTT == 0)
                            ualarm(data->RTT,0);
						RTT = data->RTT;
                        //printf("data %" PRIu32 " received\n", data->seqNum);
                        //RTT = 1000000;//for test
                        preLossRate = lossRate;
                        enQueueAndCheck(data);
                        if(lossRate > preLossRate)
                        {
                            //printf("\nalarm now\n");
                            ualarm(0,0);
                            sendDataAck(sock, &clntAddr);
                            ualarm(RTT,0);
                        }
                        //send each receive
                        //else sendDataAck(sock, &clntAddr);
                    }

                    break;
                }

            default : break;
        }
    }
    close(sock);
    printf("\nServer terminates.\n\n");
    return 0;
}