通过c

时间:2017-06-02 00:37:21

标签: c sockets network-programming file-transfer

我想实现一个程序,将任何文件从服务器传输到客户端。我必须使用读/写函数来读写数据(用于学校作业)。这是服务器和客户端的代码。

server.c

    char buffer[512];        

    if( (file = open(strTable[1], O_RDONLY)) == -1 ) { perror("Open"); }

    while( read(file, buffer, sizeof(buffer)) != 0 )
    {
        size = strlen(buffer)+1;
        if( write(newsock, &size, sizeof(size)) < 0 ) { perror("Write"); exit(1); }

        write_all(newsock, buffer, strlen(buffer)+1);
    }

    size = 4;
    if( write(newsock, &size, sizeof(size)) < 0 ) { perror("Write"); exit(1); }
    write_all(newsock, "end", 4);

它打开strTable [1](包含我想要读取的文件)它读取sizeof(缓冲区)字节,然后我发送给客户端我将写入多少字节,然后发送字节。这是write_all函数。

int write_all(int sock, char* buffer, int size)
{
   int nwrite, sent = 0;

   while( sent < size )
   {
       if( (nwrite = write(sock, buffer + sent, size - sent)) < 0 ) 
       { perror("Write"); exit(1); }

       sent += nwrite;
   }

   return sent;
}

client.c

if( (file = open(absolute, O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1 )
                { perror("Open"); }    

while( true )
        {
            received = 0;

            /* Read the desired readable size */
            if( read(sock, &size, sizeof(size)) < 0 ) 
            { perror("Read"); pthread_exit(NULL); }

            /* Read all data */
            while( received < size )
            {
                if( (nread = read(sock, buffer + received, size - received)) < 0 )
                { perror("Read"); pthread_exit(NULL); }

                received += nread;
            }

            if( strncmp(buffer, "end", 4) == 0 ) { break; }

            write_all(file, buffer, strlen(buffer)+1);
        }

客户端打开一个文件(绝对值)并在其中写入读取的内容。它首先读取它必须读取的大小,然后它不会停止读取,直到达到该大小。如果客户端读取&#34;结束&#34;然后服务器停止写入套接字,以便客户端停止读取。

问题是我无法在转移后打开文件。我读了一些我无法打开的图片。我也读了一个file.txt,我写了一些随机的单词,这似乎是正确的复制,但它也有一些垃圾(它的照片编号2)。为什么我得到这个以及如何正确地从套接字传输文件?

enter image description here

enter image description here

1 个答案:

答案 0 :(得分:1)

常见问题。 read()不会终止缓冲区,因此在其上使用strlen()作为计数无效。读/写循环应如下所示:

int count;
while ((count = read(inFD, buffer, sizeof buffer)) > 0)
{
    if (write(outFD, buffer, count) < 0)
    {
        perrror("write"); //  at least
        break;
    }
}

然后进行错误处理,如下所示:

if (count < 0)
{
    perror("read"); // at least
}

您的第二个问题是假设"end"本身将作为单独的消息收到。无法保证这一点。您将必须通过在每个文件之后关闭套接字来使用流结束,或者在每个文件之前发送长度,并且仅从流中为每个文件读取那么多字节。但是,由于您已经发送了长度,因此无论如何发送"end"都是毫无意义的。