int main(int argc, char *argv[]) { int s_listen, s_accepted; int port; struct sockaddr_in saddr, caddr; FILE *fsock_in, *fsock_out; uint caddr_len; char request_str[MAX_REQUEST_LEN]; char type[MAX_COMMAND_LEN]; char filename[MAX_FILENAME_LEN]; char buffer[DATA_CHUNK_SIZE]; char *buffer2; // for xdr int receive_requests; FILE *file; uint32_t file_size, last_modification, file_size_n, last_modification_n; struct stat sb; uint n_read; call_msg request; response_msg response; XDR xdrs_in, xdrs_out; int pid; if(argc < 2) { fprintf(stderr, "Usage: %s <port>\n", argv[0]); return 1; } port = atoi(argv[1]); if(port == 0) { fprintf(stderr, "Invalid port\n"); return 1; } saddr.sin_port = htons(port); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = INADDR_ANY; s_listen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(s_listen < 0) { perror("Impossible to create socket"); return 1; } printf("Created listen socket\n"); if(bind(s_listen, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { perror("Impossible to bind"); return 1; } printf("Socket bound to address\n"); if(listen(s_listen, BACKLOG) < 0) { perror("Impossible to listen"); return 1; } printf("Socket listen done\n"); signal(SIGPIPE, sigpipeHndlr); //signal(SIGINT, killMyChildren); for(int i = 0; i < 3; i++) { pid = fork(); if(pids[i] < 0) { printf("Impossible to create another process\n"); break; } if(pid) { // parent pids[i] = pid; } else { // child break; } } if(pid) { killMyChildren(0); return 0; } while(1) { caddr_len = sizeof(caddr); printf("Waiting for a client to connect\n"); s_accepted = accept(s_listen, (struct sockaddr *)&caddr, &caddr_len); sigpipe = 0; if(s_accepted < 0) { perror("Impossible to accept"); break; } printf("Accepted a connection from %s:%d\n", inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port)); fsock_in = fdopen(s_accepted, "r"); if(fsock_in == NULL) { perror("Impossible to do fdopen r"); close(s_accepted); continue; } fsock_out = fdopen(s_accepted, "w"); if(fsock_out == NULL) { perror("Impossible to do fdopen w"); fclose(fsock_in); close(s_accepted); continue; } xdrstdio_create(&xdrs_in, fsock_in, XDR_DECODE); xdrstdio_create(&xdrs_out, fsock_out, XDR_ENCODE); setbuf(fsock_out, 0); setbuf(fsock_in, 0); receive_requests = 1; while(receive_requests) { memset(request_str, 0, MAX_REQUEST_LEN); memset(&request, 0, sizeof(call_msg)); memset(&response, 0, sizeof(response_msg)); if(!xdr_call_msg(&xdrs_in, &request)) { printf("Error receiving request. Client closed connection\n"); break; } if(request.ctype == QUIT) { printf("Client asked to quit\n"); break; } else if(request.ctype != GET) { printf("Unknown request received\n"); break; } strncpy(filename, request.call_msg_u.filename, FILENAME_MAX); printf("Received a GET request for file: %s\n", filename); if(stat(filename, &sb)) { perror("Impossible to stat requested file"); response = ERR; xdr_response_msg(&xdrs_out, &response); continue; } if((sb.st_mode & S_IFMT) != S_IFREG) { perror("The requested file is no a regular file"); response = ERR; xdr_response_msg(&xdrs_out, &response); continue; } file_size = sb.st_size; last_modification = sb.st_mtim.tv_sec; file_size_n = htonl(file_size); last_modification_n = htonl(last_modification); file = fopen(filename, "r"); if(file == NULL) { perror("Impossible to open requested file"); fprintf(fsock_out, ERR_MSG); continue; } printf("Sending message\n"); response = OK; xdr_response_msg(&xdrs_out, &response); printf("Sending size and modification time\n"); fwrite(&file_size_n, sizeof(uint32_t), 1, fsock_out); //fwrite(&last_modification_n, sizeof(uint32_t), 1, fsock_out); printf("Sending the file\n"); while((n_read = fread(buffer, sizeof(char), DATA_CHUNK_SIZE, file)) > 0) { fwrite(buffer, sizeof(char), n_read, fsock_out); if(sigpipe) { printf("Client closed socket\n"); receive_requests = 0; fclose(file); break; } } if(!receive_requests) { break; } fclose(file); printf("File sent\n"); } xdr_destroy(&xdrs_in); xdr_destroy(&xdrs_out); fclose(fsock_out); fclose(fsock_in); close(s_accepted); } return 0; }
int main(int argc, char** argv) { char rbuf[MAXBUF]; // transmitter and receiver buffers SOCKET s; // socket struct in_addr sIPaddr; // server IP address structure struct sockaddr_in saddr; // server address structure uint16_t tport_n, tport_h; // server port number by htons() char *filename; FILE* fp; uint32_t fileBytesN, fileBytes, nNext, nLeft; ssize_t nread, nwritten; XDR xdrs_in; // Input XDR stream XDR xdrs_out; // Output XDR stream FILE* stream_socket_r; // FILE stream for reading from the socket FILE* stream_socket_w; // FILE stream for writing to the socket call_msg reqMessage; response_msg resMessage; /* Check number of arguments */ checkArg(argc, 4); prog_name = argv[0]; /* Set IP address */ setIParg(argv[1], &sIPaddr); /* Set port number */ tport_n = setPortarg(argv[2], &tport_h); /* Save the file to request */ filename = argv[3]; /* Create the socket */ fprintf(stdout, "Creating the socket...\n"); s = Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); fprintf(stdout, "- OK. Socket fd: %d\n", s); /* Prepare server address structure */ saddr.sin_family = AF_INET; saddr.sin_port = tport_n; saddr.sin_addr = sIPaddr; /* Send connection request */ fprintf(stdout, "Connecting to target address...\n"); Connect(s, (struct sockaddr*) &saddr, sizeof(saddr)); fprintf(stdout, "- OK. Connected to "); showAddress(&saddr); /* Open FILE reading stream and bind it to the corresponding XDR stream */ stream_socket_r = fdopen(s, "r"); if (stream_socket_r == NULL) { fprintf(stderr, "---ERROR. fdopen() failed.\n"); return 1; } xdrstdio_create(&xdrs_in, stream_socket_r, XDR_DECODE); /* Open FILE writing stream and bind it to the corresponding XDR stream */ stream_socket_w = fdopen(s, "w"); if (stream_socket_w == NULL) { fprintf(stderr, "---ERROR. fdopen() failed.\n"); xdr_destroy(&xdrs_in); fclose(stream_socket_r); return 1; } xdrstdio_create(&xdrs_out, stream_socket_w, XDR_ENCODE); while(1) { /* Send a file request */ reqMessage.ctype = GET; reqMessage.call_msg_u.filename = filename; if (!xdr_call_msg(&xdrs_out, &reqMessage)) { fprintf(stdout, "- ERROR sending GET message.\n"); break; } fflush(stream_socket_w); /* Receive a message */ if (!xdr_response_msg(&xdrs_in, &resMessage)) { fprintf(stdout, "- ERROR. Response xdr_response_msg() failed.\n"); break; } fprintf(stdout, "- Received response.\n"); if (resMessage == OK) { fprintf(stdout, "- File received: %s\n", filename); // Read the file size nread = read(s, (void*)&fileBytesN, sizeof(uint32_t)); fileBytes = ntohl(fileBytesN); fprintf(stdout, "- File size: %u\n", fileBytesN); // Received and write file fp = Fopen(filename, "wb"); nLeft = fileBytes; while(nLeft > 0) { if (nLeft < MAXBUF) { nNext = nLeft; } else { nNext = MAXBUF; } nread = Read(s, rbuf, nNext*sizeof(char)); nwritten = Fwrite(rbuf, sizeof(char), nNext, fp); if (nread != nNext || nwritten != nNext) { fprintf(stdout, "--- ERROR saving file.\n"); break; } nLeft -= nNext; } Fclose(fp); fprintf(stdout, "--- File written: %s\n", filename); } else if (resMessage == ERR) { fprintf(stderr, "- Received ERR message.\n"); break; } else { fprintf(stderr, "- ERROR. Something goes wrong with the communication protocol.\n"); break; } /* End the communication */ reqMessage.ctype = QUIT; reqMessage.call_msg_u.filename = NULL; if (!xdr_call_msg(&xdrs_out, &reqMessage)) { fprintf(stdout, "- ERROR sending QUIT message.\n"); break; } fprintf(stdout, "- QUIT message sent.\n"); fflush(stream_socket_r); fflush(stream_socket_w); break; } xdr_destroy(&xdrs_in); fclose(stream_socket_r); xdr_destroy(&xdrs_out); fclose(stream_socket_w); /* Close the socket connection */ fprintf(stdout, "Closing the socket connection...\n"); closesocket(s); fprintf(stdout, "- OK. Closed.\n"); return 0; }