将文件从服务器复制到客户端

时间:2017-12-10 20:40:29

标签: c sockets tcp server client

我是C的新手,我遇到了一个无法为我的生活调试的问题。我正在尝试一个非常简单的任务,即从服务器向客户端发送文件。

服务器代码:

void send_file(int socket, char *filename[100])
{

 char fname[100] = "./upload/";

 strcat(fname,filename);

 printf("%s%", fname);

 FILE *fp = fopen(fname,"rb");

    if(fp==NULL)
    {
        printf("File open error");
    }   

    while(1)
    {
        unsigned char buff[1024]={0};
        int nread = fread(buff,1,1024,fp); //read 256 byte chunk of file
        printf("Bytes read %d \n", nread);        

        // If read was success, send data. 
        if(nread > 0)
        {
            write(socket, buff, nread);
        }
        if (nread == 0)
        {
    write(socket, buff, nread);

            if (feof(fp))
    {
        printf("Transfer Complete, ID: %d\n",socket);
        break;
    }
            if (ferror(fp))

                printf("Read Error\n");

            break;
        }

    }
fclose(fp);

}

因此,对于这段代码,我获取一个文件名并以256字节块的形式读取该文件然后写入客户端随后读取的文件。

客户代码:

void get_file(int socket, char *fname[100]) {

int bytesReceived = 0;
char recvBuff[1024];
memset(recvBuff, '0', sizeof(recvBuff));

FILE *fp; 

fp = fopen(fname, "w+"); 

if(NULL == fp)
{
    printf("Error opening file");

}

//Receive data in chunks of 256 bytes 

fseek(fp, 0, SEEK_SET);//point to start of file

while(1)
{ 

bytesReceived = read(socket, recvBuff, 1024);

if (bytesReceived > 0) 
{
    fwrite(recvBuff, 1,bytesReceived,fp);
}

if (recvBuff == 0) {    
    break;
}
}

if(bytesReceived < 0)
{
    printf("\n Read Error \n");
}

printf("\nFile OK....Completed\n");
fclose(fp);

}

这个问题是双方似乎都工作但是当我在服务器端读取文件时,它读得很好,但似乎并没有发送所有这些。客户端每次都会收到大约99%的文件。

似乎客户端循环永远不会完成,因此不会写入整个文件,我使用的测试文件是jpeg,它从33010中接收32768。

哪个是1024 * 32,剩余的242个字节没有被写入,即使服务器发送一个应该打破循环的空写,循环似乎也没有结束。

向服务器发送SIGINT会结束客户端循环,但也会发送文件的其余部分。

对我做错的任何见解都会很棒,谢谢!

编辑:

按要求执行该功能的代码。

void *client_handler(void *socket_desc){

int connfd = *(int *) socket_desc;
char recv_option[128];
char filename[100];
size_t n;
size_t k;

while (1) {

char recv_option[128] = "";

readn(connfd, (unsigned char *) &n, sizeof(size_t));
readn(connfd, (unsigned char *) recv_option, n);

printf("Recieved: %c\n", recv_option[0]);

if (recv_option[0] == 'a') {
    send_servertime(connfd);
    } 

if (recv_option[0] == 'b') {
    send_uname(connfd);
}

if (recv_option[0] == 'c') {
    send_filenames(connfd);
}

if (recv_option[0] == 'd') {

  readn(connfd, (unsigned char *) &k, sizeof(size_t));
  readn(connfd, (unsigned char *) filename, k);

  send_file(connfd, &filename);

    }
}//whileloop

shutdown(connfd, SHUT_RDWR);
close(connfd);

printf("Thread %lu exiting\n", (unsigned long) pthread_self());

shutdown(connfd, SHUT_RDWR);
close(connfd);

return 0;
}  // end client_handler()

1 个答案:

答案 0 :(得分:0)

  • recvBuff == 0永远不会成真。
  • 您没有针对bytesReceived == 0进行测试,这是您应该测试的而不是recvBuff == 0

因此,您忽略了客户端中的流末尾,因此您的客户端拷贝循环永远不会退出,因此您永远不会关闭输出文件。

其他问题:

  • 请勿使用fread()fopen()等.API太存在问题。使用open()read()write()close()
  • 在文件末尾发送零字节是没有意义的。