发送文件大小,然后发送文件本身

问题描述 投票:0回答:1

客户端代码:

#include <stdio.h> 
#include <sys/socket.h> 
#include <stdlib.h> 
#include <netinet/in.h> 
#include <string.h>  
#include <netdb.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>

void error(char * msg){

    perror(msg);
    exit(0);

}

// Returns an string array from function
char *buff(const char *path){
    int end = 0;
    unsigned char * buf;
    int f_write = open(path,O_RDONLY);
    end = lseek(f_write,0,SEEK_END);
    lseek(f_write,0,SEEK_SET); 
    buf =(char*)malloc(sizeof(char*)*(end+1));
    read(f_write,buf,end);
    close(f_write);
    buf[end+1]= '\0'; 
    return buf;

}
     //connects to the socket
int connection(int portno,struct hostent * server,int sockfd){
    struct sockaddr_in serv_addr;
    int conn =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);
    conn = connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr));
    return conn;
}


int main(int argc, char *argv[]) {

    int sockfd = -1;
    int check =0;
    char projname[100]= "project1";
    int portno = -1;
    int conn = -1;
    int file_size =0;
    ssize_t len;
    int n = -1;
    struct hostent *server;
    char buffer[256];
    int fd =0;
    if(argc < 3){
        fprintf(stderr,"usage %s hostname port\n",argv[0]);
        exit(0);
    }
    // getting the portnumber
    portno = atoi(argv[2]);
    sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd < 0){
        error("Error opening socket");

    }   
    // getting the hostname
    server = gethostbyname(argv[1]);

    if(server == NULL){
        fprintf(stderr,"Error no such host\n");
        exit(0);
    }
    conn = connection(portno,server,sockfd);
    if(conn < 0){

        printf("%s\n",strerror(errno)); 

    }
    int path = open("text.txt",O_CREAT | O_WRONLY, 0644);
    if(path < 0){
        printf("%s\n",strerror(errno));
    }
    int remain_data = file_size;
    printf("Printing out the file size ");
    printf("%d\n",file_size);
    char *buffer1 = (char*)malloc(sizeof(char)*file_size+1);
    len = recv(sockfd,buffer1,BUFSIZ,0);
    printf("%d",len);
    buffer1[file_size]= '\0';
    printf("printing the sentence\n");
    printf("%s\n",buffer1);

    int total_read_bytes =0;
    int nread =0;

     return 0; 
}

服务器端代码

#include <unistd.h> 
#include <stdio.h> 
#include <sys/socket.h> 
#include <stdlib.h> 
#include <netinet/in.h> 
#include <string.h> 
#include <dirent.h>
#include <fcntl.h>
#include <sys/sendfile.h>
#include <sys/stat.h>
#include <sys/socket.h>

void error(char * msg){

    perror(msg);
    exit(1);

}

 int main(int argc, char const *argv[]){
    int sockfd =-1;
    int newsockfd = -1;
    int portno = -1;
    int clilen = -1;
    int remain_data =0;
    char buffer[300];
    char buffer1[300];
    int peer_socket = -1;
    struct sockaddr_in serv_addr,cli_addr;
    int n = -1;
    struct stat file_stat;
    char file_size[256];
    ssize_t  len;
    int sent_bytes =0;
    int path = open("project1/text.txt",O_RDONLY);
    read(path,buffer1,30);
    buffer1[31]= '\0';
    printf("%s\n",buffer1);
    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);
    int fd = open("project1/text.txt",O_RDONLY);
    fstat(fd,&file_stat);

    clilen = sizeof(cli_addr);

    peer_socket = accept(sockfd,(struct sockaddr *)&cli_addr, &clilen);

    sprintf(file_size,"%d",file_stat.st_size);
    //sends file size
    len = send(peer_socket,file_size,sizeof(file_size),0);

    if(peer_socket <0){

            error("Error on accept");       

    }

    off_t offset = 0;
    remain_data = file_stat.st_size;
    //send the file
    while(((sent_bytes=sendfile(peer_socket,fd,&offset,remain_data))>0) &&( remain_data>0)){
            fprintf(stdout,"1.Server sent %d bytes from files 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 files data, offest is not: %d and remaing data = %d\n",sent_bytes, offset,remain_data);

    }
    return 0;
}

我能够从服务器端获取文件的大小,但我无法从客户端的服务器获取文件内容。我的客户打印出一个空白的空间,文件的数据应该是,我不知道我是否正确使用recv函数正确的文件。 P.S我明白我必须在完成后关闭插座。

c sockets recv
1个回答
2
投票

为了安全性和健壮性,您必须检查所调用的所有标准库函数的返回值以检查错误。但是,对于recv()read(),您必须检查并正确处理返回值的正确性。这些函数不保证传输所请求的全部字节数,而对于网络连接,它们并不常见。如果要完全传输特定数量的字节,则必须准备使用多个recv()read()调用来执行此操作,通常通过在循环中调用函数。

您没有检查recv()呼叫的返回值,因此如果您有一个简短的读取 - 或者如果有错误或远程端关闭连接而没有发送任何东西 - 那么您的客户将不会注意到,并且将简单地输出碰巧在缓冲区中的垃圾。

© www.soinside.com 2019 - 2024. All rights reserved.