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; }
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); }
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; }