因此,此代码适用于高达20KB的小文件,但是当我尝试发送或接收较大的文件时,它会在某些时候停止读取。客户端和服务器的两个功能,用于发送和接收文件。我知道它可能有一些泄漏和东西但我稍后会解决。起初我希望它能够正常工作。 BUF_SIZE = 512
// SENDING BYTES
void send_bytes(int connfd, int client_number, char **command_parts)
{
FILE *fp;
fp = fopen(command_parts[1], "r");
int i = 0;
// FINDING BYTE SIZE OF THE FILE
fseek(fp, 0, SEEK_END); /* PUTTING FILE POINTER TO THE END OF THE FILE */
int num_of_bytes = ftell(fp);
fseek(fp, 0, SEEK_SET); /* RESETTING FILE POINTER TO THE BEGINNING OF THE FILE */
char *sendbuff = malloc(num_of_bytes * sizeof(char));
memset(sendbuff, '\0', num_of_bytes);
// SENDING TOTAL BYTES TO SEND
while (write(connfd, itoa(num_of_bytes), 10) < 0)
{
}
printf("\nClient #%d --> Size of file sent: %d\n", client_number, num_of_bytes);
// IF BYTES MORE THAN 512 SENDING IT IN PARTS
if(num_of_bytes > BUF_SIZE)
{
int bytes_left_to_send = num_of_bytes;
char *tempbuff = calloc(BUF_SIZE, sizeof(char));
while(bytes_left_to_send > 0)
{
if(bytes_left_to_send >= BUF_SIZE)
{
// READING 512 BYTES AND PASSING IT TO TEMPBUFF
for (i = 0; i < BUF_SIZE; i++)
{
fread(&tempbuff[i], 1, 1, fp);
}
// SENDING BYTES
while (write(connfd, tempbuff, BUF_SIZE) < 0)
{
}
bytes_left_to_send = bytes_left_to_send - BUF_SIZE;
memset(tempbuff, '\0', BUF_SIZE);
}
else
{
// READING 512 BYTES AND PASSING IT TO TEMPBUFF
for (i = 0; i < bytes_left_to_send; i++)
{
fread(&tempbuff[i], 1, 1, fp);
}
// SENDING BYTES
while (write(connfd, tempbuff, bytes_left_to_send) < 0)
{
}
bytes_left_to_send = bytes_left_to_send - bytes_left_to_send;
memset(tempbuff, '\0', BUF_SIZE);
}
}
}
else
{
// READING EACH BYTE AND PASSING IT TO SENDBUFF
for (i = 0; i < num_of_bytes; i++)
{
fread(&sendbuff[i], 1, 1, fp);
}
// SENDING BYTES
while (write(connfd, sendbuff, num_of_bytes) < 0)
{
}
}
// FREEING MEMORY
fclose(fp);
free(sendbuff);
printf("\nClient #%d --> File sent\n", client_number);
}
// RECEIVING BYTES
void recv_bytes(int connfd, int client_number, char **command_parts)
{
int bytes_read = 0, bytes_read_in_total = 0, i = 0;
char *num_of_bytes = malloc(10 * sizeof(char));
char *recvbuff = NULL;
FILE *fp;
fp = fopen(command_parts[2], "w");
// RECEIVING BYTES TO RECEIVE
while (read(connfd, num_of_bytes, 10) < 0)
{
}
printf("\nClient #%d --> Size of file received: %d\n", client_number, atoi(num_of_bytes));
recvbuff = malloc(atoi(num_of_bytes) * sizeof(char)); /* ALLOCATING recvbuff WITH RECEIVED SIZE */
memset(recvbuff, '\0', atoi(num_of_bytes));
// IF BYTES MORE THAN 512 RECEIVING IT IN PARTS
if(atoi(num_of_bytes) > BUF_SIZE)
{
int bytes_left_to_read = atoi(num_of_bytes);
char *tempbuff = calloc(BUF_SIZE, sizeof(char));
while(bytes_left_to_read > 0)
{
if(bytes_left_to_read >= BUF_SIZE)
{
// READING BYTES
while (bytes_read = read(connfd, tempbuff, BUF_SIZE) < 0)
{
}
bytes_read = strlen(tempbuff);
// WRITING BYTES READ SO FAR TO THE FILE
for (i = 0; i < bytes_read; i++)
{
fwrite(&tempbuff[i], 1, 1, fp);
}
bytes_left_to_read = bytes_left_to_read - bytes_read;
memset(tempbuff, '\0', BUF_SIZE);
}
else
{
// READING BYTES
while (bytes_read = read(connfd, tempbuff, bytes_left_to_read) < 0)
{
}
bytes_read = strlen(tempbuff);
// WRITING BYTES READ SO FAR TO THE FILE
for (i = 0; i < bytes_read; i++)
{
fwrite(&tempbuff[i], 1, 1, fp);
}
bytes_left_to_read = bytes_left_to_read - bytes_read;
memset(tempbuff, '\0', BUF_SIZE);
}
}
}
else
{
// RECEIVING BYTES
while (bytes_read_in_total < atoi(num_of_bytes))
{
while (bytes_read = read(connfd, recvbuff, atoi(num_of_bytes)) < 0)
{
}
bytes_read = strlen(recvbuff);
bytes_read_in_total = bytes_read_in_total + bytes_read;
// WRITING BYTES READ SO FAR TO THE FILE
for (i = 0; i < bytes_read; i++)
{
fwrite(&recvbuff[i], 1, 1, fp);
}
memset(recvbuff, '\0', atoi(num_of_bytes));
}
}
free(recvbuff);
fclose(fp);
printf("\nClient #%d --> File received\n", client_number);
}
答案 0 :(得分:-1)
我以前做过这件事,我需要很长时间才能给你答案。 首先,您必须知道在调用send()时Linux内核不会发送整个缓冲区。其次,知道文件大小后需要的部分是以块的形式发送给接收端。我做了512个字节,你可以把它增加到你喜欢的任何地方。接收端也应该以块的形式接收,直到收到所有字节为止。
int sendall(int s, void *buf, int *len)
{
int total = 0; // how many bytes we've sent
int bytesleft = *len; // how many we have left to send
int n;
while (total < *len) {
n = send(s, buf+total, bytesleft, 0);
if (n == -1) {
break;
}
total += n;
bytesleft -= n;
}
*len = total; // return number actually sent here
return n==-1?-1:0; // return -1 on failure, 0 on success
}
使用此来接收整个缓冲区
int recvall(int s, void * buf,int *len)
{
// the workbuffer for storing currently received buffer
char workbuffer[*len];
// Holds the number of received bytes */
int total = 0;
// Holds the number of sent bytes
int n;
//holds the number of bytes left to received
int bytesleft = *len;
while (total < *len)
{
// recv and append to workbuffer
n = recv(s,workbuffer+total,bytesleft,0);
if (n== -1 || n == 0) {
break;
}
// increment total by the number of received bytes
total += n;
bytesleft -= n;
}
// Copy workbuffer to to buf
memcpy(buf,workbuffer,sizeof(workbuffer));
switch(n)
{
case -1:
return -1;
break;
case 0:
return 0;
break;
default:
return total;
}
你可以下载我写的小程序quad(Qucik上传和下载)。基本上它应该演示如何传输大文件。这是https://www.dropbox.com/s/xpqhflgx6ps89vq/quad.zip?dl=0
wget https://www.dropbox.com/s/xpqhflgx6ps89vq/quad.zip?dl=0 -O quad.zip
unzip quad.zip
cd quad/src
make clean
sudo apt-get install libncurses-dev
make
#uploading: ./quad -v -u -i /home/me/myfile.txt -a 0.0.0.0 -p 4444
#downloading: ./quad -v -d -l 4444 -o /home/me/Downloads