我正在尝试将文件从客户端发送到服务器。它有时有效,有时无效。当第一次尝试发送文件时,它发送损坏的文件,并且在服务器端形成的文件端是其大小的两倍。但在第一次尝试后,所有尝试都会成功传输。谁能帮我解决这个问题吗?
客户端.c
message msg;
msg.type = SEND_FILE;
char *username, *filename;
username = strtok(input+6, " ");
filename = strtok(NULL, "");
//Get Picture Size
printf("Getting Picture Size\n");
FILE *picture;
picture = fopen(filename, "r");
int size;
fseek(picture, 0, SEEK_END);
size = ftell(picture);
fseek(picture, 0, SEEK_SET);
//Send Picture Size
printf("Getting Picture Size\n");
sprintf(msg.data, "%d", size);
strncpy(msg.username, username, 20);
if(send(connection->socket, &msg, sizeof(message), 0) < 0)
{
perror("Send failed");
exit(1);
}
//Send Picture as Byte Array
printf("Sending Picture as Byte Array\n");
char send_buffer[size+1];
fread(send_buffer, 1, sizeof(send_buffer), picture);
write(connection->socket, send_buffer, sizeof(send_buffer));
bzero(send_buffer, sizeof(send_buffer));
服务器.c
//Read Picture Size
printf("Reading Picture Size\n");
int size = atoi(message_text);
//Read Picture Byte Array
printf("Reading Picture Byte Array\n");
char p_array[size];
printf("Converting Byte Array to Picture %d\n", size);
FILE *image;
image = fopen("c4.png", "w");
int readSize = 0;
while (readSize < size) {
readSize = readSize + read(clients[sender].socket, p_array, size);
fwrite(p_array, 1, sizeof(p_array), image);
}
fclose(image);
最佳答案
对于初学者:
您不想在每个 fwrite()
上存储相同数量的字节
fwrite(p_array, 1, sizeof(p_array), image);
但只是实际读取的字节数。
sizeof(p_array)
返回 p_array
的大小,它是 size
乘以 char
的大小。后者被定义为1
。
除此之外,对 read()
的调用完全缺乏错误检查,以及测试对方是否关闭连接。这并没有领先太远。
要解决这个问题,你可以这样做:
#include <errno.h> /* for errno */
...
size_t size = atoi(message_text);
printf("Reading Picture Byte Array\n");
char p_array[size];
size_t readSize = 0;
while (readSize < size) {
ssize_t result = read(clients[sender].socket, p_array, size); /* Mind the ssize_t, it's *not* size_t! */
if (0 >= result)
{
if (0 == result)
{
fprintf(stderr, "The other end gracefully shut down the connection.\n");
break;
}
else
{
if (EINTR == errno) /* got interrupted, start over */
{
continue;
}
if (EAGAIN == errno) /* in case reading from a non-blocking socket: no data available, start over */
{
continue;
}
/* Something went wrong unrecoverable. */
perror("read() failed");
break;
}
}
else
{
fwrite(p_array, 1, result, image);
/* Also add error checking here! */
readSize += result;
}
}
关于c - 从客户端到服务器的文件传输,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39056508/