天天看點

linux下udp大檔案傳輸

 http://bbs.chinaunix.net/thread-633761-1-1.html

近日小弟做了個linux下使用者資料報協定大檔案傳輸程式發上來與大家共勉。

代碼在 redhat 9.0 下編譯通過。

最大測試無差錯傳輸檔案:288M

最大測試傳輸速度:6.5M/S

可能這裡并不需要這種類型的文章,但希望各位能代小弟轉貼,因為網絡上很難搜尋到這種可以解決丢包問題的代碼級實作方法,希望每一個需要的人都能看的到。

伺服器端:

#include<sys/socket.h>;

#include<string.h>;

#include<netinet/in.h>;

#include<stdio.h>;

#include<stdlib.h>;

#include<fcntl.h>;

#include<sys/stat.h>;

#include<unistd.h>;

#include<errno.h>;

#include<sys/select.h>;

#include<sys/time.h>;

#include<unistd.h>;

#include<sys/types.h>;

#define SERV_PORT 2500

#define MAX_SIZE 1024*40

void recvUDP(char name[20],int sockfd)

{

        int ret,fd;

        mode_t fdmode = (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);

        char mesg[MAX_SIZE];

        fd_set rdset;

        struct timeval tv;

        int rlen,wlen;

        int i;

        fd = open(name,O_RDWR|O_CREAT|O_APPEND,fdmode);

        if(fd == -1)

        {

                printf("open file %s error:%n",name,strerror(errno));

                exit(-1);

        }

        for(i=0;;i++)

        {

                tv.tv_sec = 1;

                tv.tv_usec = 0;

                FD_ZERO(&rdset);

                FD_SET(sockfd,&rdset);

                ret = select(sockfd+1,&rdset,NULL,NULL,&tv);

                if(ret == -1)

                {

                        printf("select error %s\n",strerror(errno));

                        exit(-1);

                }

                else if(ret==0)

                {

                        printf("select timeout,continue circle\n");

                        continue;

                }

                if(FD_ISSET(sockfd,&rdset))

                {

                        memset(mesg,0,MAX_SIZE);

                        rlen = read(sockfd,mesg,MAX_SIZE);

                        if(rlen <=0 )

                        {

                                printf("read error %s\n",strerror(errno));

                                exit(-1);

                        }

                        if(!strcmp(mesg,"end"))

                        {

                                printf("recv end.\n");

                                break;

                        }

                        wlen = write(fd,mesg,rlen);

                        if(wlen != rlen )

                        {

                                printf("write error %s\n",strerror(errno));

                                exit(-1);

                        }       

                }

                printf("The %d times write\n",i);

        }

        close(fd);

}

int main(int argc, char *argv[])

{

        int sockfd;

        int r;

        struct sockaddr_in servaddr;

        sockfd = socket(AF_INET,SOCK_DGRAM,0);

        bzero(&servaddr,sizeof(servaddr));

        servaddr.sin_family = AF_INET;

        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

        servaddr.sin_port = htons(SERV_PORT);

        if(bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) == -1)

        {

                perror("bind error");

                exit(-1);

        }

        r = fcntl(sockfd, F_GETFL, 0);

        fcntl(sockfd, F_SETFL, r & ~O_NONBLOCK);

        recvUDP(argv[1],sockfd);

        return 0;

}

用戶端:

#include<sys/types.h>;

#include<sys/socket.h>;

#include<string.h>;

#include<netinet/in.h>;

#include<stdio.h>;

#include<stdlib.h>;

#include<arpa/inet.h>;

#include<fcntl.h>;

#include<sys/stat.h>;

#include<errno.h>;

#include<sys/sysinfo.h>;

#include<sys/select.h>;

#include<sys/time.h>;

#include<unistd.h>;

#define MAX_SIZE 1024*40

#define SERV_PORT 2500

void connectUDP(char name[20],int sockfd,struct sockaddr *pservaddr,socklen_t servlen)

{

                char buf[MAX_SIZE];

                fd_set wrset;

                struct timeval tv;

                int rlen,wlen;

                int fd;

                int ret;

                int i;

                if(connect(sockfd,(struct sockaddr *)pservaddr,servlen) == -1)

                {

                        perror("connet error");

                        exit(1);

                }

                else

                        printf("connect server ok!\n");

                fd = open(name,O_RDONLY);

                if(fd==-1)

                {

                        printf("fopen error %s\n",strerror(errno));

                        exit(-1);

                }

                i=0;

                while(1)

                {       

                        tv.tv_sec = 1;

                        tv.tv_usec = 0;

                        FD_ZERO(&wrset);

                        FD_SET(sockfd,&wrset);

                        ret = select(sockfd+1,NULL,&wrset,NULL,&tv);

                        if(ret == -1)

                        {

                                printf("select error %s\n",strerror(errno));

                                exit(-1);

                        }

                        else if(ret==0)

                        {

                                printf("select timeout,continue circle\n");

                                continue;

                        }

                        memset(buf,0,MAX_SIZE);

                        if(FD_ISSET(sockfd,&wrset))

                        {                                       

                                rlen = read(fd,buf,MAX_SIZE);

                                if(rlen <0)

                                {

                                        printf("fread data error %s\n",strerror(errno));

                                        exit(-1);

                                }

                                else if(rlen==0)

                                {

                                        wlen = write(sockfd,"end",3);

                                        if(wlen !=3)

                                        {

                                                printf("write end error\n",strerror(errno));

                                                exit(-1);

                                        }

                                        printf("all complete\n");

                                        close(fd);

                                        close(sockfd);

                                        exit(0);

                                }

                                wlen = write(sockfd,buf,rlen);

                                if(wlen != rlen)

                                {

                                        printf("write data to sockfd error:%s\n",strerror(errno));

                                        exit(-1);

                                }

                                i++;

                                usleep(500);

                                printf("The %d times read\n",i);

                        }

                }

        }

int main(int argc ,char *argv[])

{       

        char *fh;

        struct sysinfo s_info;

        float time1,time2;

        int error1,error2;

        int sockfd;

        struct stat fsize;

        struct sockaddr_in servaddr;

        error1= sysinfo(&s_info);

        time1 = s_info.uptime;

        int r;

        if(argc != 3)

        {

                printf("useage:udpclient<IPaddress>;\n");

                exit(1);

        }

        bzero(&servaddr,sizeof(servaddr));

        servaddr.sin_family= AF_INET;

        servaddr.sin_port = htons(SERV_PORT);

        if(inet_pton(AF_INET,argv[1],&servaddr.sin_addr) <= 0)

        {

                printf("[%s]is not a valid IPaddress\n",argv[1]);

                exit(1);

        }

        fh = argv[2];

        sockfd =socket(AF_INET,SOCK_DGRAM,0);

        r = fcntl(sockfd, F_GETFL, 0);

        fcntl(sockfd, F_SETFL, r & ~O_NONBLOCK);

        connectUDP(argv[2],sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));       

        fprintf(stderr,"ServerIP:\t%s\n",argv[1]);       

        if(stat(argv[2],&fsize) == -1)

                perror("failed to get fiel statusi\n");

        else       

                fprintf(stderr,"file name:\t%s\nfile size:\t%dK\n",argv[2],fsize.st_size/1024);

        error2=sysinfo(&s_info);

        time2 = s_info.uptime;

        printf("tranfice file time =%fs\n",(time2-time1));

}               

Makefile

  1. all:send recv
  2. send:send.c
  3.         gcc -Wall send.c -o send
  4. recv:recv.c
  5.         gcc -Wall recv.c -o recv
  6. clean:
  7.         rm -rf send recv

繼續閱讀