void dg_cli(int sockfd, struct sockaddr_in* servcaddr, int servlen) { char recvline[MAXLINE], sendline[MAXLINE], addr[MAXLINE]; int n, port; if (inet_ntop(AF_INET, &servcaddr -> sin_addr.s_addr, addr, MAXLINE) == NULL) { perror("inet_ntop error"); exit(1); } port = ntohs(servcaddr -> sin_port); while (fgets(recvline, MAXLINE, stdin) != NULL) { if ((n = sendto(sockfd, recvline, strlen(recvline), 0, (struct sockaddr*)servcaddr, servlen)) < 0) { perror("sendto error"); exit(1); } if ((n = readable_timeout(sockfd, 5)) == 0) { fprintf(stderr, "socket recvfrom timeout\n"); exit(1); } else { n = recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL); recvline[n] = '\0'; printf("%s", recvline); } } }
/* check readable when timeout in seconds usec */ int readable_timeout_sec( int fd, int sec) { return readable_timeout( fd, sec, 0 ); }
/* check readable when timeout in mircoseconds usec */ int readable_timeout_millisec( int fd, int millisec) { return readable_timeout( fd, 0, millisec * 1000 ); }
/* check readable when timeout in mircoseconds usec */ int readable_timeout_usec( int fd, int usec) { return readable_timeout( fd, 0, usec ); }
void dg_cli(int sockfd, const struct sockaddr *pservaddr, socklen_t servlen) { int n,connection_sockfd,attempt_count,success_flag; char sendline[MAXLINE], recvline[MAXLINE + 1]; struct sockaddr_in servaddr; //Bind and print client socket addr. cliaddr.sin_addr.s_addr = htonl(cliaddr.sin_addr.s_addr); printf("\nClient will use: %s\n",inet_ntoa(cliaddr.sin_addr)); cliaddr.sin_family = AF_INET; cliaddr.sin_port = htons(0); if (bind(sockfd, (struct sockaddr *) &cliaddr,sizeof(cliaddr))) err_sys_p("Coudlnt bind socket."); printf("[INFO] Bounded to %s\n", (char*)Sock_ntop((struct sockaddr * ) &cliaddr,sizeof(cliaddr))); //Connect to well known port of the server if (connect(sockfd, (struct sockaddr *) pservaddr, servlen) < 0) { err_sys_p("Connect error"); } //Send the filename as datagram int len = strlen(required_file_name); if (write(sockfd, required_file_name, len) != len) { err_sys_p("Write error.Server is unreachable"); } success_flag=0; for(attempt_count=0;attempt_count<MAX_ATTEMPT;attempt_count++){ if(readable_timeout(sockfd,TIMEOUT_SEC,TIMEOUT_USEC)==0){ printf("Socket timeout...attempt %d failed.\n",attempt_count); if (write(sockfd, required_file_name, len) != len) { //Try again err_sys_p("Write error.Server is unreachable"); } }else{ success_flag=1; break; } } if(success_flag==0){//TODO what to do if MAX_ATTEMT fail? report and end prgm? err_sys_p("Socket timeout...max no. of attempt failed.\n"); } //Read the new connection socket ephemeral port number. This serves as ack for filename too. if ((n = read(sockfd, recvline, MAXLINE)) == -1) err_sys_p("Read error. Server is unreachable"); recvline[n] = 0; // null terminate fputs(recvline, stdout); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(atoi(recvline)); if (inet_pton(AF_INET, serverIP, &servaddr.sin_addr) != 1) err_sys_p("Cannot convert string IP to binary IP."); connection_sockfd = sockfd; if (connect(connection_sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) { err_sys_p("Connect error"); } //Send connected ack strcpy(sendline, "ACK_CONNECTED"); if (write(connection_sockfd, sendline, strlen(sendline)) != strlen(sendline)) { err_sys_p("Write error.Server is unreachable"); } printf("%s\n",sendline); // fflush(NULL); //Read the file and print output. while (1) { if ((n = read(connection_sockfd, recvline, MAXLINE)) == -1) err_sys_p("Read error. Server is unreachable"); else if (n == 0) break; recvline[n] = 0; // null terminate fputs(recvline, stdout); //send ACK /*int len = strlen(sendline); if (write(connection_sockfd, sendline, len) != len) { err_sys("Write error.Server is unreachable"); }*/ } printf("[INFO] File transfer completed.\n"); }