我不知道为什么它会进入一个无限循环,并且在我尝试执行该命令行时不会下载该文件:
./ server 2000
./ client get filename localhost 2000 256
我有两个疑问。第一个是为什么文件列表上带有一些点。第二个是我无法从服务器目录下载文件的原因。
客户端代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#include <arpa/inet.h>
void error(const char *msg)
{
perror(msg);
exit(0);
}
int main(int argc, char *argv[])
{
int file_size;
FILE *received_file;
int remain_data = 0;
ssize_t len;
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[256];
int TamBuffer;
if (argc < 3) {
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
if(strcmp(argv[1],"list")==0){
TamBuffer=atoi(argv[4]);
char *comando = argv[1];
portno = atoi(argv[3]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(argv[2]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
n=write(sockfd,comando,strlen(comando));
if (n < 0)
error("ERROR writing to socket");
bzero(buffer,TamBuffer);
bzero(buffer,TamBuffer);
n = read(sockfd,buffer,TamBuffer-1);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n",buffer);
close(sockfd);
}
if (strcmp(argv[1],"get")==0){
TamBuffer=atoi(argv[5]);
char *comando = argv[1];
portno = atoi(argv[4]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(argv[3]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
strcat(comando,argv[2]);
n=write(sockfd,comando,strlen(comando));
if (n < 0)
error("ERROR writing to socket");
/* Receiving file size */
recv(sockfd, buffer, TamBuffer, 0);
file_size = atoi(buffer);
fprintf(stdout, "\nFile size : %d\n", file_size);
received_file = fopen("newfile", "w");
if (received_file == NULL)
{
fprintf(stderr, "Failed to open file foo --> %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
remain_data = file_size;
while (((len = recv(sockfd, buffer, TamBuffer, 0)) > 0) && (remain_data > 0))
{
fwrite(buffer, sizeof(char), len, received_file);
remain_data -= len;
int received_byte = len;
fprintf(stdout, "Receive %d bytes and we hope :- %d bytes\n", received_byte, remain_data);
}
fclose(received_file);
close(sockfd);
}
return 0;
}
服务器代码
#include <errno.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <sys/sendfile.h>
void error(const char *msg)
{
perror(msg);
exit(1);
}
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno;
socklen_t clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
int sent_bytes = 0; // bytes de envio de arquivo
char file_size[256]; //tamanho do arquivo
struct stat file_stat;
off_t offset;
int remain_data;
ssize_t len;
int fd;
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr,
&clilen);
if (newsockfd < 0)
error("ERROR on accept");
bzero(buffer,256);
n = read(newsockfd,buffer,255);
if (n < 0) error("ERROR reading from socket");
if(strcmp("list",buffer)==0){
DIR *d;
struct dirent *dir;
d = opendir(".");
if (d)
{
while ((dir = readdir(d)) != NULL)
{
n=write(newsockfd,dir->d_name,strlen(dir->d_name));
n=write(newsockfd, "\n",1);
if (n < 0) error("ERROR writing to socket\n");
}
closedir(d);
}
}
else {
n = read(newsockfd,buffer,255);
if (n < 0) error("ERROR reading from socket");
int i;
for(i=0;i<strlen(buffer);i=i+1){
buffer[i]=buffer[3+i];
}
printf("%s\n",buffer);
char* FILE_TO_SEND = buffer;
fd = open(FILE_TO_SEND, O_RDONLY);
if (fd == -1)
{
fprintf(stderr, "Error opening file --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
/* Get file stats */
if (fstat(fd, &file_stat) < 0)
{
fprintf(stderr, "Error fstat --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
int num_filesize = file_stat.st_size;
fprintf(stdout, "File Size: \n%d bytes\n", num_filesize);
/* Sending file size */
len = send(newsockfd, file_size, sizeof(file_size), 0);
if (len < 0)
{
fprintf(stderr, "Error on sending greetings --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
printf("teste1/n");
int num_bytes_sent= len;
fprintf(stdout, "Server sent %d bytes for the size\n", num_bytes_sent);
offset = 0;
remain_data = file_stat.st_size;
/* Sending file data */
printf("teste2/n");
while (((sent_bytes = sendfile(newsockfd, fd, &offset, 256)) > 0) && (remain_data > 0))
{
fprintf(stdout, "1. Server sent %d bytes from file's data, offset is now : %d and remaining data = %d\n", sent_bytes, offset, remain_data);
remain_data -= sent_bytes;
fprintf(stdout, "2. Server sent %d bytes from file's data, offset is now : %d and remaining data = %d\n", sent_bytes, offset, remain_data);
}
}
close(newsockfd);
close(sockfd);
return 0;
}