我是靠谱客的博主 鲜艳未来,最近开发中收集的这篇文章主要介绍Linux下用UDP实现文件传输,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

UDP编程框图

                                         

        UDP协议中服务器和客户端的交互存在于数据的收发过程中。

        进行网络数据收发的时候,服务器和客户端的数据是对应的:客户端发送数据的动作,对服务器来说是接收数据的动作;客户端接收数据的动作,对服务器来说是发送数据的动作。

     实现文件的传输大概分为这几个步骤:

  1. 客户端读文件,将内容放在client_buffer中
  2. 客户端通过sendto发送client_buffer中的数据
  3. 服务器端通过recvfrom对数据进行接收,存到server_buffer中
  4. 将数据写入文件中,关闭文件,关闭套接字

直接来代码:

服务器端:

// udp_file_server.c

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

#define BUFFER_SIZE 1024

int main()
{
    int sockfd,n;
    struct sockaddr_in server,client;
	int addrlen=sizeof(struct sockaddr);
    char filename[100];
    char filepath[100];

    char *buffer;//file buffer
    int fileTrans;

    buffer = (char *)malloc(sizeof(char)*BUFFER_SIZE);
    printf("init bufferSize=%d  SIZE=%dn",sizeof(buffer),BUFFER_SIZE);
    bzero(buffer,BUFFER_SIZE); 
    int lenfilepath;
    FILE *fp;
    int writelength;

    if((sockfd = socket(AF_INET,SOCK_DGRAM,0))<0)
    {
        printf("socket build error!n");
    }
    else
    {
        printf("socket build success!n");
    }
    memset(&server,0,sizeof(server));  //清空server结构体
    server.sin_family= AF_INET;
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    server.sin_port = htons(8888);

    if((bind(sockfd,(struct sockaddr*)&server,sizeof(server)))==-1)
    {
        printf("bind error!n");
    }
    else
    {
        printf("bind success!n");
    }
    
    while(1)
    {
	    printf("waiting....n");
            memset(filename,'',sizeof(filename));
            memset(filepath,'',sizeof(filepath));
            lenfilepath = recvfrom(sockfd,filepath,100,0,(struct sockaddr *)&client,&addrlen);
            printf("filepath :%sn",filepath);
            if(lenfilepath<0)
            {
                printf("recv error!n");
				return -1;
            }
            else
            {
                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 :%sn",filename);
            fp = fopen(filename,"w");
            if(fp!=NULL)
            {
		int times = 1;
                while(fileTrans =recvfrom(sockfd,buffer,BUFFER_SIZE,0,(struct sockaddr *)&client,&addrlen))
                {
			printf("times = %d   ",times);
			times++;
                    if(fileTrans<0)
                    {
                        printf("recv2 error!n");
                        break;
                    }

                    writelength = fwrite(buffer,sizeof(char),fileTrans,fp);

                    if(fileTrans < BUFFER_SIZE)
                    {
                        printf("finish writing!n");
                        break;
                    }else{
			//printf("write succ! %d fileTrans=%dn",writelength,fileTrans);
			printf("write successful!n");
			//break;
		    }
		printf("continuen");
                    bzero(buffer,BUFFER_SIZE); 
                }
                printf("recv finished!n");
                fclose(fp);
            }
            else
            {
                printf("filename is null!n");

            }
    }
    close(sockfd);
    return 0;
}

客户端:

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

#define BUFFER_SIZE 1024

int main()
{
    int sockcd;
    struct sockaddr_in server;
    char filepath[100];//file to translate
    int addrlen=sizeof(struct sockaddr);

    FILE *fp;
    int lenpath; //filepath length
    char *buffer;//file buffer
    int fileTrans;
    buffer = (char *)malloc(sizeof(char)*BUFFER_SIZE);
    bzero(buffer,BUFFER_SIZE); 

    if((sockcd = socket(AF_INET,SOCK_DGRAM,0))<0)
    {
        printf("socket build error!n");
    }
    memset(&server,0,sizeof(server));
    server.sin_family= AF_INET;
    server.sin_port = htons(8888);
    if(inet_pton(AF_INET,"127.0.0.1",&server.sin_addr)<0)
    {
        printf("inet_pton error!n");
    }

    printf("file path:n");
    scanf("%s",filepath);//get filepath

    fp = fopen(filepath,"r");//opne file
    if(fp==NULL)
    {
        printf("filepath not found!n");
        return 0;

    }
    printf("filepath : %sn",filepath);
    lenpath = sendto(sockcd,filepath,strlen(filepath),0,(struct sockaddr *)&server,addrlen);// put file path to sever 
    if(lenpath<0)
    {
        printf("filepath send error!n");
    }
    else
    {
        printf("filepath send success!n");
    }
    //sleep(1);
    printf("begin send data...n");
    int times = 1;
    while((fileTrans = fread(buffer,sizeof(char),BUFFER_SIZE,fp))>0)
    {
	sleep(1);  //注意这里
	printf("times = %d   ",times);
	times++;
        //printf("fileTrans =%dn",fileTrans);
        if(sendto(sockcd,buffer,fileTrans,0,(struct sockaddr *)&server,addrlen)<0)
        {
            printf("send failed!n");
            break;      
        }
	else{
	    printf("send successful!n");
	}
	if(fileTrans < BUFFER_SIZE) break;
        bzero(buffer,BUFFER_SIZE); 
    }
    //printf("fileTrans =%dn",fileTrans);
    fclose(fp);
    close(sockcd);
    return 0;
}

在实现过程中,出现了这样一种情况:

        在收发大文件时,客户端发送正常,服务器总是只能收到前一部分文件内容,后面的全部丢包。

在经过各种调试之后,发现在发数据时,客户端一直在循环不断的发送数据,发送太快,而服务器来不及接收 。

在每次发送数据时,sleep一会,这个问题就解决了。

效果图:

运行......

结果:

最后

以上就是鲜艳未来为你收集整理的Linux下用UDP实现文件传输的全部内容,希望文章能够帮你解决Linux下用UDP实现文件传输所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(54)

评论列表共有 0 条评论

立即
投稿
返回
顶部