1. 程式人生 > >linux c伺服器與客戶端之間的檔案傳輸

linux c伺服器與客戶端之間的檔案傳輸

最近做了一下linux C網路方面的專案,簡單的寫了一下伺服器於客戶端之間上傳,下載檔案,利用併發伺服器,可以實現多個客戶端同時上傳,下載。
寫的不好,還請大神多多指教!多的不說,一切都在程式碼中,部分程式碼如下所示:

/*server.c */ 伺服器端
void *recvmation(void *arg)	//接收客戶端傳送過來的資訊,執行緒
{
	int my_fd = *((int *)arg);
	int n;
		
	while(1)
	{	
		n = recv(my_fd, (struct regis *)&RecvReg, sizeof(RecvReg), 0);
		if(n == -1)
		{
			perror("fail1 to receive!\n");
			//exit(1);
		}
		else if(n == 0)
		{
			continue;   //如果客戶端斷開連線,伺服器繼續監聽接收
		}

		printf("filename:%s\n", RecvReg.filename);
		printf("flag = %s\n", RecvReg.flag);
		printf("my_fd = %d\n", my_fd);

		if(strncmp(RecvReg.flag, "sendfile", 8) == 0)   //客戶端上傳檔案到伺服器
		{
			char Send_Filename[FILE_NAME];
			strcpy(Send_Filename, RecvReg.filename);
			recvfile(my_fd, Send_Filename);   //接受客戶端發來的檔案
		}
		if(strncmp(RecvReg.flag, "lookfile", 8) == 0)   //客戶端從伺服器下載檔案
		{
			char Down_Filename[FILE_NAME];
			DIR *dp = NULL;
			struct dirent *dirp;
			if((dp = opendir("/root/server/dai")) == NULL)    //查詢並輸出當前資料夾下的所有檔案 //此路徑可以根據自己需要修改
				printf("cannot open\n");
			while((dirp = readdir(dp)) != NULL)
			{
				printf("%s\n",dirp->d_name);
				strcpy(D_File.Dir_File, dirp->d_name);
				if(send(my_fd, (struct DIR_FILE *)&D_File, sizeof(D_File), 0) < 0)
					break;
				usleep(1000);	//睡眠函式延遲,這個必須有,因為是非阻塞
				bzero((struct DIR_FILE *)&D_File, sizeof(D_File));
			}
			closedir(dp);
			send(my_fd, "OK", 2, 0);
		}
		if(strncmp(RecvReg.flag, "downfile", 8) == 0)   //客戶端從伺服器下載檔案
		{
			char Down_Filename[FILE_NAME];
			strcpy(Down_Filename, RecvReg.filename);
			sendfile(my_fd, Down_Filename);   //客戶端從伺服器下載檔案
		}
	}
	
	close(my_fd);			//完成所有操作後,關閉該檔案描述符
}

void sendfile(int sfd, char Down_Filename[])   //向客戶端傳送檔案
{
	char file_name[FILE_NAME];
	char buffer[BUFFER_SIZE];      
	char Path[Path_SIZE];
	
	strcpy(file_name, Down_Filename);
   
	printf("%s\n", file_name);  
	sprintf(Path, "/root/server/dai/%s", file_name);       //此路徑可以根據自己需要修改
	// 開啟檔案並讀取檔案資料      
	FILE *fp = fopen(Path, "r");   

	if(NULL == fp)      
	{        
		printf("File:%s Not Found\n", file_name);      
	}      
	else     
	{        
		bzero(buffer, BUFFER_SIZE);        
		int length = 0;        // 每讀取一段資料,便將其傳送給客戶端,迴圈直到檔案讀完為止 

		while((length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)        
		{          
			printf("length = %d\n", length);
			if(send(sfd, buffer, length, 0) < 0)          
			{            
				printf("Send File:%s Failed.\n", file_name);            
				break;          
			}          
			bzero(buffer, BUFFER_SIZE);        
		}           // 關閉檔案        
		fclose(fp);   
		sleep(1);//延遲  //睡眠函式延遲,這個必須有,因為是非阻塞
		send(sfd, "OK", 2, 0);   
		printf("File:%s Transfer Successful!\n", file_name);      
	}      // 關閉與客戶端的連線      
}

void recvfile(int sfd, char Send_Filename[])   //接受客戶端發來的檔案
{
	char file_name[FILE_NAME];
	char buffer[BUFFER_SIZE];
	char Path[Path_SIZE];
	strcpy(file_name, Send_Filename);
  
	printf("%s\n", file_name);   
	sprintf(Path, "/root/server/dai/%s", file_name);      //此路徑可以根據自己需要修改
	// 開啟檔案並讀取檔案資料      
	FILE *fp = fopen(Path, "w");   

	if(NULL == fp)      
	{        
		printf("File:%s Not Found\n", file_name);      
	}   
	bzero(buffer, BUFFER_SIZE);    
	int length = 0;  
	while((length = recv(sfd, buffer, BUFFER_SIZE, 0)) > 0)    
	{      
		printf("length = %d\n", length);
		if(strcmp(buffer, "OK") == 0)
		{
			break;
		}
		if(fwrite(buffer, sizeof(char), length, fp) < length)      
		{        
			printf("File:\t%s Write Failed!\n", file_name);        
			break;      
		}
   
		bzero(buffer, BUFFER_SIZE);    
	}       // 接收成功後,關閉檔案,關閉socket    
	printf("Receive File:\t%s From Server IP Successful!\n", file_name);    
	fclose(fp);    
}
/*client.c*/客戶端
void recvfile(int client_socket_fd, char Down_Filename[])		//客戶端從伺服器下載檔案
{    
	char file_name[FILE_NAME];
	char buffer[BUFFER_SIZE];
	        
	strcpy(file_name, Down_Filename);         
	// 向伺服器傳送buffer中的資料    

	FILE *fp = fopen(file_name, "w");    
	if(NULL == fp)    
	{      
		printf("File:\t%s Can Not Open To Write\n", file_name);      
		exit(1);    
	}       
	// 從伺服器接收資料到buffer中    
	// 每接收一段資料,便將其寫入檔案中,迴圈直到檔案接收完並寫完為止    
	bzero(buffer, BUFFER_SIZE);    
	int length = 0;  
	
	while((length = recv(client_socket_fd, buffer, BUFFER_SIZE, 0)) > 0)    
	{      
		printf("length = %d\n", length);
		if(strcmp(buffer, "OK") == 0)
		{
			break;
		}
		if(fwrite(buffer, sizeof(char), length, fp) < length)      
		{        
			printf("File:\t%s Write Failed\n", file_name);        
			break;      
		}      
		bzero(buffer, BUFFER_SIZE);    //在這裡注意使用清空函式,否則會發生意想不到的錯誤   
	}       // 接收成功後,關閉檔案,關閉socket    
	printf("Receive File:\t%s From Server IP Successful!\n", file_name);    
	fclose(fp);  
	printf("client_socket_fd = %d\n", client_socket_fd);  
}

void sendfile(int client_socket_fd, char Send_Filename[])    //上傳檔案到伺服器
{   
	char file_name[FILE_NAME]; 
	char buffer[BUFFER_SIZE];   
	   
	strcpy(file_name, Send_Filename); 
	
	// 開啟檔案,準備寫入      
	FILE *fp = fopen(file_name, "r");   

	if(NULL == fp)      
	{        
		printf("File:%s Not Found\n", file_name);      
	}      
	else     
	{        
		bzero(buffer, BUFFER_SIZE);        //在這裡注意使用清空函式,否則會發生意想不到的錯誤   
		int length = 0;        // 每讀取一段資料,便將其傳送給客戶端,迴圈直到檔案讀完為止 
		while((length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)        
		{          
			printf("length = %d\n", length);
			if(send(client_socket_fd, buffer, length, 0) < 0)          
			{            
				printf("Send File:%s Failed.\n", file_name);            
				break;          
			}    			   
			bzero(buffer, BUFFER_SIZE);     //在這裡注意使用清空函式,否則會發生意想不到的錯誤   
		}  sleep(1);        // 關閉檔案       //睡眠函式延遲,這個必須有,因為是非阻塞 
		fclose(fp); 
		send(client_socket_fd, "OK", 2, 0);       
		printf("File:%s Transfer Successful!\n", file_name);    
	}      // 關閉與客戶端的連線      
}

另外還有新增linux c下MySQL資料庫實現登陸註冊介面