通过C中的套接字发送大文件

编程入门 行业动态 更新时间:2024-10-22 20:25:31
本文介绍了通过C中的套接字发送大文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

因此,此代码适用于最大20KB的小文件,但当我尝试发送或接收大文件时,它有时会停止读取.客户端和服务器的两个功能,用于发送和接收文件.我知道它可能会有一些泄漏和问题,但我稍后会修复.首先,我希望它能正常工作.BUF_SIZE = 512

So this code works ok for small files of up to 20KB but when i try to send or receive larger files it stops reading at some point. Two functions for client and server, to send and receive files. I know it might have some leaks and stuff but I will fix that later. At first I want it to work properly. 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); }

推荐答案

我之前已经做过,我需要花一些时间才能给出答案.首先,您必须知道,调用send()时Linux内核不会发出整个缓冲区.其次,在知道文件大小之后,所需的部分是将其分块发送到接收端.我做了512个字节,您可以将其增加到您喜欢的任何大小.接收端也应分块接收,直到接收到所有字节为止.

I have done this before, It would take length for me to give you the answer. First you have to know that the Linux kernel will not send out the whole buffer when you invoke send(). Secondly the part that is required after you know the file size is to then send it in chunks to the receiving end. I did 512 bytes, you could increase it to whatever you like. The receiving end should also receive in chunks until all of the bytes are received.

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 }

用这个来接收整个缓冲区

Use this one to receive a whole buffer

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上传和下载).基本上,它应该演示如何传输大文件.这是 www.dropbox/s/xpqhflgx6ps89vq/quad.zip?dl=0

You can download the small program I wrote, quad (Qucik Upload and Download). Basically it should demonstrate how large files are transferred. Here's the www.dropbox/s/xpqhflgx6ps89vq/quad.zip?dl=0

wget www.dropbox/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

更多推荐

通过C中的套接字发送大文件

本文发布于:2023-11-25 17:38:10,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1630706.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:大文件

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!