通过套接字传输文件c
我想实现一个程序,将任何文件从服务器传输到客户端。我必须使用读/写功能读取和写入数据(用于学校作业)。这里是服务器和客户端的代码。通过套接字传输文件c
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);
}
客户端打开一个文件(绝对),并在其所写的东西它读取。它首先读取它需要读取的尺寸,然后它不会停下来读取,直到达到该尺寸。如果客户端读取“结束”,则服务器已停止写入套接字,以便客户端停止读取。
问题是我无法打开转移后的文件。我读了一些我无法打开的图像。我还读了一个file.txt,我写了一些随机单词,这似乎被复制了,但它也有一些垃圾(其照片编号为2)。为什么我得到这个以及如何正确地从套接字传输文件?
常见的问题。 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"
无论如何都毫无意义。
您还需要检查来自'write'的返回值,因为它可能写入少于count个字节,在这种情况下,您需要再次写入调用才能写入更多。 –
特别是在非阻塞模式下。某些特定的底层对象(如管道和文件)可能会保证小于某个限制的写入不会返回短值,但是您需要检查计数实际上是否小于该限制,并且outFD是限制适用的某些内容... –
@ChrisDodd对不起,我误解了。根据Posix规范,不在*阻止*模式,但我应该检查错误。 – EJP
[tag:encoding]的相关性使我不知所措。 – EJP
'read'和'write'都返回读取或写入的字节数,这可能比请求的少。 –