修改了一下以前文件传输的问题,包括文件传输块即字符串长度太小的问题,文件文件名称可以添加目录的问题,主要针对的是大型文件从客户端向服务器发送时的速度和规范的问题。
客户端:
/*
*************************************************
*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的速度并不会因此得到改变,所以这种方法一定程度上比之前写的这个程序要好很多,但是感觉速率如何提升又是个新问题值得我慢慢的摸索。