基于TCP的文件传输

修改了一下以前文件传输的问题,包括文件传输块即字符串长度太小的问题,文件文件名称可以添加目录的问题,主要针对的是大型文件从客户端向服务器发送时的速度和规范的问题。

客户端:

/*
 *************************************************
 *Name : TCP_Client.c                                                                           *
 *Date : 2016-01-26                                                                              *
 *Author : sniper                                                                                    * 
 *Aim : Client send the file to the Server.                                           *
 *************************************************
 */

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>

#define BUFFER_SIZE                100*1024*1024  
#define FILE_NAME_MAX_SIZE         512  

int main(int argc,char *argv[])
{
	int socketfd;
	struct sockaddr_in s_add,c_add;
	unsigned short portnum = 0x22B8;
	int len;
	char *buffer;  
	FILE *fp ;
	int file_block_length = 0;  
	
	/*
	 *Pay attention to this place. Dynamic is the better way.
	 */
	buffer = (char *)malloc(sizeof(char)*BUFFER_SIZE);
	/*
	 *Create the socket
	 */
	if((socketfd=socket(AF_INET,SOCK_STREAM,0))<0)
	{
		printf("Socket create error! \n");
		exit(1);
	}
	
	/*
	 *set the address format
	 */	
	bzero(&s_add,sizeof(struct sockaddr_in));
	s_add.sin_family = AF_INET;
	/*
	 *change the VM address
	 */
	s_add.sin_addr.s_addr = inet_addr("192.168.0.120");//change the string to 32-bit internet byte.
	s_add.sin_port=htons(portnum);
	
	if (connect(socketfd,(struct sockaddr *)(&s_add),sizeof(struct sockaddr))<0)
	{
		printf("Connect failure!\n");
		return -1;
	}
	else
		printf("Connect Success!\n");
	
	/*
	 *Send the file
	 */	
	char filepath[1000];
	printf("please input the file's path : ");
	scanf("%s",filepath);
	fp = fopen(filepath, "r");  
	
	char filename[1000];
	memset(filename,'\0',sizeof(filename));
	int i=0,k=0;
	for(i=strlen(filepath);i>=0;i--)
	{
		if(filepath[i]!='/')	
		{
			k++;
		}
		else 
			break;	
	}
	strcpy(filename,filepath+(strlen(filepath)-k)+1);
	printf("filename is %s \n",filename);
	
	/*
	 *Send the file name to Server.
	 */
	len=send(socketfd,filename,strlen(filename),0);
	if(len<0)  
        {  
            printf("send error!\n");  
            exit(1);  
        }
	else   
        {  
            printf("Send succeed send : %s \n",filename);  
        }  

	printf("**************************************\n");
	
	sleep(3);

	/*
	 *Send the file to Server.
	 */ 
	if (fp == NULL)  
	{  
		printf("File: file Not Found!\n");  
	}  
	else  
	{  
		bzero(buffer, BUFFER_SIZE);  		
		while( (file_block_length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)  
		{  
		    printf("file_block_length = %d\n", file_block_length);  

			/*
			 *Send the string to the buffer  
			 */
		    if (send(socketfd, buffer, file_block_length, 0) < 0)  
		    {  
		        printf("Send File:test Failed!\n");  
		        break;  
		    }  

		    bzero(buffer, sizeof(buffer));  
		}  
		fclose(fp);  
		printf("File:file Transfer Finished!\n");  
	}
	close(socketfd);  
	
	return 0;
}

对于上面程序中提示要注意的地方,具体的内容可以看我另一篇文章对于这个问题的分析。

服务器端:

/*
 ************************************************
 *Name : TCP_Server.c                                                                       *
 *Date : 2016-01-26                                                                           *
 *Author : sniper                                                                                 *
 *Aim : Server can receive big file.                                                   *
 ************************************************
 */

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <sys/socket.h>
#include <pthread.h>

int socketfd_connect = 0;
pthread_t ntid;
int len = 0;

#define BUFFER_SIZE 100*1024*1024
#define FILE_NAME_MAX_SIZE 512

void *print_message(void *arg)
{
        /*
         *define the buffer to receive the file
         */
        int pthread_socket_connect;
        int i=0;
        int write_length;
        FILE *fp;
        char *buffer;
        int length = 0;

        /*
         *Pay attention to this place
         */
        buffer = (char *)malloc(sizeof(char)*BUFFER_SIZE);

	bzero(buffer,BUFFER_SIZE);
        pthread_socket_connect = socketfd_connect;
        pthread_detach(ntid);

        /*
         *receive the file name
         */
        char filename[1000];

        memset(filename,'\0',sizeof(filename));
        len=recv(socketfd_connect,filename,100,0);
        if(len<0){
                printf("receive error!\n");
                exit(1);
        }
        else
                printf("%d receive message is %s\n",__LINE__,filename);

        /*
         *Receive the file
         */
	 fp = fopen(filename,"w");
        if(NULL == fp )
        {
                printf("File:\t Can Not Open To Write\n");
                exit(1);
        }

        while( length = recv(pthread_socket_connect,buffer,BUFFER_SIZE,0))
        {
                if(length < 0)
                {
                    printf("Recieve Data From Client Failed!\n");
                    break;
                }

                /*
                 *write the buffer to the file
                 */
                write_length = fwrite(buffer,sizeof(char),length,fp);
                if (write_length<length)
                {
                    printf("File:file Write Failed\n");
                    break;
                }
                bzero(buffer,BUFFER_SIZE);
        }
        printf("Recieve File: %s  From Client Finished\n",filename);
        fclose(fp);
        pthread_exit(0);
}

int main(int argc,char *argv[])
{
        int socketfd_listen;
        struct sockaddr_in server_addr,client_addr;
        unsigned short portnum = 0x22B8;
        int err;

        /*
         *Create the socket
         */
        if((socketfd_listen=socket(AF_INET,SOCK_STREAM,0))<0)
        {
                printf("Socket create error! \n");
                exit(1);
        }

        /*
         *set the address format
         */
        bzero(&server_addr,sizeof(struct sockaddr_in));
        server_addr.sin_family=AF_INET;
        server_addr.sin_addr.s_addr=inet_addr("192.168.0.120");
        server_addr.sin_port=htons(portnum);

        if(bind(socketfd_listen,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))<0)
        {
                printf("bind failure!\n");
                return -1;
        }
        printf("bind Success!\n");

        if(listen(socketfd_listen,5)<0)
        {
                printf("Listen failure!\n");
                return -1;
        }

        len=sizeof(struct sockaddr);
      	/*
         *Using the loop to send and receive the message.
         */
        while(1)
        {
                socketfd_connect = accept(socketfd_listen, (struct sockaddr *)(&client_addr), &len);

                if(socketfd_connect<0)
                {
                        printf("accept fail !\n");
                        return -1;
                }

                err = pthread_create(&ntid,NULL,print_message,NULL);
                if(err!=0)
                        printf("can't create pthread!\n");
        }

        close(socketfd_listen);
        close(socketfd_connect);
        return 0;
}

文件传输这个问题,这种是一种解决方案,会不会有其他的解决方案,这个还要我再摸索摸索,开始的时候把BUFFER_SIZE开大,会有一定的加快速率,但是随着自己给的值越大,慢慢的文件内容写入buffer的速度并不会因此得到改变,所以这种方法一定程度上比之前写的这个程序要好很多,但是感觉速率如何提升又是个新问题值得我慢慢的摸索。



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值