精华内容
参与话题
问答
  • 工具: C++/MFC   原理: 1. 服务器与客户端之间的通讯,通过socket套接字 2. 一个电脑有一个ip地址,和6万多的端口号 ...3. 当一个socket被创建,就会有一个ip和端口号联系到socket上 ...4. 一个应用程序,可以...

    工具:

    C++/MFC

     

    原理:

    1.      服务器与客户端之间的通讯,通过socket套接字

    2.      一个电脑有一个ip地址,和6万多的端口号

    3.      当一个socket被创建,就会有一个ip和端口号联系到socket上

    4.      一个应用程序,可以设置多个端口,即:客户端可以设置多个socket

    5.      一个电脑相当于ip,电脑上的应用程序的一个功能相当于一个端口(4,5点的理解很重要)

    6.      需要使用线程,因为sendto和recvfrom函数是阻塞的

    7.      C(客户端)与S(服务器)之间的传递时通过数据包(char*)

    8.      需要发送的信息,可以通过设计char*格式或者结构体来发送过去,即,C整合数据,S解析数据,然后在两端分别处理

     

    思想:

    1.      UDP多人聊天:

    <1>多人聊天意思不是多人在一个地方群聊(当然这个实现很简单),这里我要说的是,客户端之间可以相互聊天,point2point,别人不知道内容。那么,服务器这时候扮演的是一个邮局的身份,而两个客户端就是发信人和收信人,发信人,把需要发送的信放到邮箱里面,然后邮局会过来取,那么邮局就会通过收信人的地址,把信投递到当地的邮箱中,然后收信人过来取,那么服务器就相当于一个转接员。在程序中的体现是服务器端保存所有登陆的用户名和他们对应的IP地址和端口号,当收到一个用户的请求的时候,就开始搜索,指定用户的IP和端口号,然后把相应的信息,发送到目标IP和端口号上,这就完成了C/S之间的通讯。

    <2>这里需要掌握的知识是,套接字库的初始化,创建套接字,学会使用sendto和recvfrom,

    这里要注意的是sendto和recvfrom是阻塞函数,意思就是,如果recvfrom这个函数没有收到数据,他就会卡在那里,直到接收到数据,sendto也是阻塞的具体百度。

    服务器的处理方式就很简单了,设置结构体USERINFO,内有用户名(这里的用户名,一定要是唯一标识,类似于QQ号码),然后还有一个sockaddr_in结构体变量,此结构体用来保存一个IP和一个端口号,定义一个vector的容器,其他容器同样可以,当一个客户端发送连接请求的时候,把USERINFO赋值,然后推送到vector容器内,保存此用户的信息。这就是我的服务器一端的大体思路。

    <3>需要学会线程的使用,原因很简单,因为sendto和recvfrom函数的阻塞的,不可以在主线程里面运行,不然主界面会卡死。(具体内容可以百度Afxbeginthread)

    <4>接下来,说一下客户端的思路,客户端首先要发送连接请求,然后开线程进行发消息工作,这一部分最主要的就是消息的整合,我的消息整合是MSG_TYPE-FROMNAME-TONAME-TEXT,然后将这个消息发送过去,即可,当用户推出时发送下线消息。

     

    2.      UDP文件传输:

    <1>大体就是通过二进制方式读取文件,然后通过sendto和recvfrom进行传输,然后再以二进制方式写入文件。

    <2>首先发送文件名和文件大小,目的是为了让接收端(这里为什么说叫接收端,因为,服务器和客户端都可以作为接收端,可以有文件的上传和下载得知)能够创建文件,并且开辟足够大的内存空间去准备接收发来的数据,因为,一个UDP包的大小最大为64k,那么显然当文件过大的时候64k是远远不够的,那么怎么办呢?我们可以把文件拆成很多个包,然后发送过去,然后再在接收端进行整合,这里需要知道一个知识点当发送端把很多的数据包发送给接收端的时候,数据包并不是按照发送的次序到达,也就是说,我发送的第五十个数据包,可能比发送的第十个数据包更早的到达接收端,那么这样一来,如果按照数据的接收顺序写入文件的话,就会出错,例如,发送了五个单词,h,e,l,l,o,那么如果按照接收顺序写入的话,他会可能会写入e,l,h,l,o。所以需要给每一个数据包编号,然后再在接收端整合。

     

    3.      遇到的问题和解决方法:

    <1>结构体是否可以作为数据包进行传输?

               可以,结构体可以强行转化为char*,但是值得注意的是结构体的大小问题,不是sizeof(结构体变量),具体百度。

     

    <2>为什么会丢包?

            接收端接到数据后需要分析数据包,那么必定要花费一定的时间,如果发送端发的数据包的速度过快比如不去sleep,或者sleep时间过短,那么,发送端发送的包,可能在接收端处理上一个包的时候就丢掉了,其实数据包被传到了端口处,如果没有东西接收他的话,那么他就会被丢掉,所以发送端的文件发送,时间间隔要把握一下。

     

    <3>一个端口可以向两个,多个,不同的目的端口发送数据包,但是一个端口不能同时接收两个端口发来的信息,为什么会这样?

               因为之前也提到过了,recvfrom函数是阻塞的,当这个sock在接收消息时候,如果没有接收到,那么他就会一直停滞在那里,那么又有人会问了,sendto函数不也是阻塞的吗?为啥它可以呢?这里不是说他不会那样,只是因为我们无需开一个线程去不停的给对方发送消息,也就是说,我啥时候给别人发送,我就啥时候sendto一下就好了,但是recvfrom需要不停地接收,在一个线程里面,那么这个全局变量sock就会一直被这个线程使用,所以如果再让他来接收消息,那么就是无法接收的。

     

    <4>如何实现单个客户端同时上传下载文件?

               如果只是一个客户端的话,只需要将服务器,发送文件的代码放到线程里就好了,但是如果服务器还要处理其他其他用户的请求的话,那就可以上传一个端口,下载一个端口。

     

    <5>多个客户端上传下载

             我想的方法很笨,因为,不想在一个端口接收所有人的数据包,那样会很慢,而且很容易丢包,然后我就想这在服务器建立多个端口,然后每一个端口用一个线程去维护,然后当一个客户端不需要文件传输服务的时候,就可以把这个端口让出来,让其他人使用,当需要的时候可以向服务器申请,然后服务器发一个没有任务的端口,然后客户端建立连接,进行通讯。

    <6>推出进程,需要发送,功能结束消息之后break

     

    没有学习很深,只是在做课设过程中遇到的一些问题,和自己的解决方法,我处理的方法很菜也很水,望指教。

     

    展开全文
  • udp文件发送
  • 服务器端 #include <stdio.h> #include <stdlib.h> #include <winsock2.h> #include <windows.h> #pragma comment(lib, "ws2_32.lib") #define BUFSIZE 512 ... char buf[BUFSI...

    服务器端

    #include <stdio.h>
    #include <stdlib.h>
    #include <winsock2.h>
    #include <windows.h>
    #pragma comment(lib, "ws2_32.lib")
    
    #define	BUFSIZE 512
    
    typedef struct
    {
    	char buf[BUFSIZE];
    	int id;
    }packInfo;
    
    typedef struct
    {
    	int id;
    	int status;
    }backInfo;
    
    int serverSocketInit()
    {
    	//执行WSAStarup函数
    	WSADATA wsaData;
    	WORD sockVersion = MAKEWORD(2, 2);
    	if (WSAStartup(sockVersion, &wsaData) != 0)
    	{
    		return 0;
    	}
    	
    	//执行socket函数
    	SOCKET serSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);			//使用UDP协议
    	if (serSocket == INVALID_SOCKET)
    	{
    		printf("socket error !");
    		return 0;
    	}
    	
    	//规定地址的一些参数
    	struct sockaddr_in serAddr;
    	serAddr.sin_family = AF_INET;
    	serAddr.sin_port = htons(8888);
    	serAddr.sin_addr.S_un.S_addr = INADDR_ANY;
    	
    	//执行bind函数,将socket与地址Addr绑定
    	if (bind(serSocket, (struct sockaddr*) & serAddr, sizeof(serAddr)) == SOCKET_ERROR)
    	{
    		printf("bind error !");
    		closesocket(serSocket);
    		return 0;
    	}
    	return serSocket;
    }
    
    int serverRecvMessage(packInfo* pack, int serSocket, struct sockaddr_in* p_remoteAddr)
    {
    	int nAddrLen = sizeof(*p_remoteAddr);
    	int ret = recvfrom(serSocket, pack, sizeof(packInfo), 0, (struct sockaddr*)  p_remoteAddr, &nAddrLen);
    
    	if (ret < 0)
    	{
    		return -1;
    	}
    	printf("recv %d bytes\n", ret);
    	return ret;
    }
    
    int serverSendMessage(backInfo* back,int serSocket, struct sockaddr_in* p_remoteAddr)
    {
    	int ret = sendto(serSocket, (char*) back, sizeof(back), 0, p_remoteAddr, sizeof(struct sockaddr_in));
    	if (ret < 0)
    	{
    		printf("send to error\n");
    		return -1;
    	}
    	//printf("send %d bytes\n", ret);
    	return ret;
    }
    
    int main()
    {
    	int fd = serverSocketInit();
    	struct sockaddr_in* p_remoteAddr = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));
    	packInfo pack = { 0,0,{0}};
    	backInfo back;
    	
    
    	printf("waiting for message...\n");
    	int ret = 0;
    
    	back.id = 1;
    	pack.id = 0;
    	if ((ret = serverRecvMessage(&pack, fd, p_remoteAddr))== -1)
    	{
    		printf("the first package recv error");
    		exit(1);
    	}
    	FILE* fp = fopen("filepath", "a+");
    	fwrite(pack.buf, 1, BUFSIZE - 1, fp);
    
    	//Sleep(150);
    	while (1) 
    	{
    
    		if (serverSendMessage(&back, fd, p_remoteAddr) == -1)
    		{
    			printf("send error! pack_id:%d\n",back.id);
    			continue;
    		}
    		//printf("strlen:%d\n", strlen(pack.buf));
    		if (strlen(pack.buf) < BUFSIZE-1)
    		{
    			//printf("buf size:%d\n", strlen(pack.buf));
    			//printf("buf :%s", pack.buf);
    			break;
    		}
    		memset(pack.buf, 0, sizeof(pack.buf));
    		if (ret = serverRecvMessage(&pack, fd, p_remoteAddr) == -1)
    		{
    			printf("recv error! pack_id:%d\n", back.id+1);
    		}
    		else
    		{
    			printf("%d", pack.id);
    			//pack.id++;
    		}
    		//printf("pack.id : %d\n", pack.id);
    		if (pack.id == (back.id+1))
    		{
    			back.id++;
    			//printf("%s\n", pack.buf);
    			fwrite(pack.buf, 1,BUFSIZE-1, fp);
    			printf("success recv pack id:%d\n", pack.id);
    		}
    		else
    		{
    			printf("failed recv pack id[%d]\n", pack.id+1);
    		}
    	}
    	closesocket(fd);
    	fclose(fp);
    	return 0;
    }
    

    其中的filepath自定义或者通过客户端传输(在传输文件信息前进行一次通信)。

    其中的backInfo用于验证包,backInfo.id表示服务器接受到的最新包。backInfo.status暂时未使用。

    客户端

    #include <stdio.h>
    #include <stdlib.h>
    #include <winsock2.h>
    #include <windows.h>
    #pragma comment(lib, "ws2_32.lib")
    
    #define BUFSIZE 512
    #pragma pack(1)
    typedef struct
    {
    	char buf[BUFSIZE];
    	int id;
    }packInfo;
    #pragma pack()
    
    typedef struct
    {
    	int id;
    	int status;
    }backInfo;
    
    int clientSocketInit()
    {
    	//执行WSAStarup函数
    	WSADATA wsaData;
    	WORD sockVersion = MAKEWORD(2, 2);
    	if (WSAStartup(sockVersion, &wsaData) != 0)
    	{
    		return 0;
    	}
    
    	//执行socket函数
    	SOCKET cliSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);			//使用UDP协议
    	if (cliSocket == INVALID_SOCKET)
    	{
    		printf("socket error !");
    		return 0;
    	}
    	return cliSocket;
    }
    
    int clientSendMessage(packInfo* pack,int cliSocket, struct sockaddr_in* p_serAddr)
    {
    	int ret = sendto(cliSocket, (char*)pack, sizeof(packInfo), 0, p_serAddr, sizeof(struct sockaddr_in));
    	if (ret < 0)
    	{
    		//printf("send error\n");
    		return -1;
    	}
    	printf("send %d bytes\n", ret);
    	return ret;
    }
    
    int clientRecvMessage(backInfo* back,int cliSocket)
    {
    	int ret = recvfrom(cliSocket, (char*)back,sizeof(backInfo),0,NULL,NULL);
    	if (ret < 0)
    	{
    		//printf("recv error\n");
    		return -1;
    	}
    	//printf("recv %d bytes\n", ret);
    	return ret;
    }
    
    int main()
    {
    	int port = 8888;
    	char addr[] = "127.0.0.1";
    
    
    	SOCKET cliSocket = clientSocketInit();
    
    	//规定对于客户端的目的地址的一些参数
    	struct sockaddr_in serAddr;
    	serAddr.sin_family = AF_INET;
    	serAddr.sin_port = htons(port);
    	serAddr.sin_addr.S_un.S_addr = inet_addr(addr);
    
    	char* filename = "filepath";
    
    	FILE* fp = fopen(filename, "rt+");
    	if (fp == NULL)
    	{
    		printf("file open error");
    		exit(1);
    	}
    
    	backInfo back;
    
    	int id = 1;
    	printf("按回车键开始传输文件");
    	system("pause");
    
    	while (1)
    	{
    		rewind(fp);
    		packInfo pack;
    		pack.id =  id;
    		//printf("pack.id:%d\n", pack.id);
    		//system("pause");
    
    		if (fseek(fp, (pack.id-1)*(BUFSIZE - 1), SEEK_SET) != 0)
    		{
    			printf("fseek error");
    			fclose(fp);
    			//system("pause");
    			exit(1);
    		}
    
    		int fret = fread(pack.buf, 1, BUFSIZE-1, fp);
    		if (fret == 0)
    		{
    			printf("发送结束\n");
    			break;
    		}
    		pack.buf[fret] = '\0';
    		//printf("fret = %d\n", fret);
    		//printf("send message %s", pack.buf);
    		if (clientSendMessage(&pack, cliSocket, &serAddr) == -1)
    		{
    			printf("send error pack id:%d\n", pack.id);
    			continue;
    		}
    		if (clientRecvMessage(&back, cliSocket) == -1)
    		{
    			printf("recv error pack id:%d\n", pack.id);
    		}
    		//printf("back.id : %d\n", back.id);
    		if (pack.id == back.id)
    		{
    			printf("\nsuccess pack id:%d\n", pack.id);
    			id++;
    		}
    		memset(pack.buf, 0, BUFSIZE);
    	}
    	fclose(fp);
    	closesocket(cliSocket);
    	return 0;
    }
    

    由于fread函数返回值是count(坑人),而不是读取的字节数,为了获得读取的字节数,此处直接使用了每次读取1个字节的方式。如果希望有更高的效率可以据此加以改进。

    代码中的filepath可自定义,或者添加一段代码用以从命令行获取文件路径。

    总结

    • UDP通信中的大文件传输相对于TCP更为复杂,需要对每一个包进行验证,同时每次服务器接收到包时需要对客户端进行反馈,客户端应当在接受到反馈确保服务器收到后再发送下一个包。
    • 为了方便验证包的信息,故定义了packInfo结构体,在此,由于recvfromsendto函数中对于缓冲区的要求为char*,故对此要进行类型转换,此时需要尤为注意结构体的字节对齐。
    • 本例未测试是否可以在中间某包未发送成功情况下再次重发此包(仅仅写了代码没有经过验证)
    展开全文
  • linux下udp大文件传输

    2011-07-29 20:18:12
    http://bbs.chinaunix.net/thread-633761-1-1.html... 近日小弟做了个linux下用户数据报协议大文件传输程式发上来与大家共勉。 代码在 redhat 9.0 下编译通过。 最大测试无差错传输文件:288M 最大测试传输速度:6.5

     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); /*create a socket*/

            /*init servaddr*/
            bzero(&servaddr,sizeof(servaddr));
            servaddr.sin_family = AF_INET;
            servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
            servaddr.sin_port = htons(SERV_PORT);

            /*bind address and port to socket*/
            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.        
    7. clean:
    8.         rm -rf send recv


     


     


     

    展开全文
  • UDP发送大型文件_不丢包

    千次阅读 2017-11-05 17:27:51
    先上图1:如果对文件要求不高的话 ,可以使用UDPUDP在实际测试中,丢包还是听验证的,但是效率高2:如果文件必须完整,还是使用TCP 。Socket进行文件传输,比较稳妥近期的项目中要是用软件升级,系统文件有600M 。...

    先上图


    1:如果对文件要求不高的话 ,可以使用UDP,UDP在实际测试中,丢包还是听验证的,但是效率高

    2:如果文件必须完整,还是使用TCP 。Socket进行文件传输,比较稳妥


    近期的项目中要是用软件升级,系统文件有600M 。一般的程序员会说,下载吗 ,直接下载安装就好了 ,我也是这样想的 ,素不知线下的网络的环境 有多差,当时一个业务员和我说,要是能实现手机发送文件给设备就好了,毕竟大家都是用手机的,不然太浪费时间了 ,因为当时用的是腾讯的Im来实现即时通讯的,利用外网来发送文件,

    那么问题就来了 ,这么大 ,要多久才能发完 ,那就用局域网来发送文件吧 ,第一个想到的就是UDP来实现 ,测试中发现DUP丢包问题特别明显,当时死活都找不到原因 ,后来把发送的次数和接受的次数对比打印了一下 ,命名发送了2k次,接收端只接受了500次,OK ,问题就是发送太快了 ,那么就让发送端发慢一点,

    Thread.sleep(10);  一般设置5就OK了,这个可以根据自己的设备来设定休眠的时间

    这样就解决问题了 ,

    源码地址 :http://pan.baidu.com/s/1i4MB40l

    好的,直接看代码吧 ,

    1:新建一个Service,利用Bind的形式来开启服务 ,这样不必一直在后台运行 ,service中开启线程池 ,这样降低重建线程的次数,降低内存的消耗

    package com.example.administrator.canchatdemo.service;
    
    import android.app.Service;
    import android.content.Context;
    import android.content.Intent;
    import android.os.Binder;
    import android.os.IBinder;
    import android.util.Log;
    
    import com.example.administrator.canchatdemo.http.MessageReceiveRunnable;
    import com.example.administrator.canchatdemo.http.MsgSendRunable;
    import com.example.administrator.canchatdemo.http.UdpSend;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class SocketService extends Service {
    
        private static final String TAG = "message";
        private MyBinder binder = new MyBinder();
        // 设定固定数量线程的线程池
        ExecutorService executor = Executors.newFixedThreadPool(10);
    
        @Override
        public void onCreate() {
            super.onCreate();
            Log.i(TAG, "=======SocketService_onCreate");
        }
    
        public void sendMessage(String data, String ip, int port) {
            Runnable runnable = new MsgSendRunable(data, ip, port);
            executor.execute(runnable);
        }
    
        public void receiveMessage(Context context, int port) {
            Runnable runnable = new MessageReceiveRunnable(context, port, true);
            executor.execute(runnable);
        }
    
    
        public void sendFileMessage(String filePath, String ip, int port) {
            Runnable runnable = new UdpSend(filePath, ip, port);
            executor.execute(runnable);
        }
    
    
    //    public void receiveFileMessage(int port) {
    //        Runnable runnable = new UdpReceive(port);
    //        executor.execute(runnable);
    //    }
    
    
        public class MyBinder extends Binder {
            public SocketService getService() {
                return SocketService.this;
            }
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            return START_NOT_STICKY;
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            return binder;
        }
    
        @Override
        public boolean onUnbind(Intent intent) {
            return false;
        }
    
        @Override
        public void onDestroy() {
            Log.i(TAG, "=======onDestroy");
            MessageReceiveRunnable.stopReceMessage(); //停止接受消息
            super.onDestroy();
        }
    }
    

    2:新建发送文件的Runnable

    package com.example.administrator.canchatdemo.http;
    
    import android.util.Log;
    
    import com.example.administrator.canchatdemo.entity.SendFileEntity;
    
    import org.greenrobot.eventbus.EventBus;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    
    public class UdpSend implements Runnable {
    
    
        public static DatagramPacket dataPacket;
    
    
        String filePath;
        private int port;
        private String ip;
    
        public UdpSend(String filePath, String ip, int port) {
            this.filePath = filePath;
            this.port = port;
            this.ip = ip;
        }
    
    
        @Override
        public void run() {
            sendFile();
        }
    
        public void sendFile() {
            sendMessage(SendFileEntity.STATE_START, 0, "开始发送文件");
            Log.i("message", "准备发送文件");
            try {
                File file = new File(filePath);
                if (!file.exists()) {
                    Log.i("message", "文件不存在");
                    sendMessage(SendFileEntity.STATE_FAILED, 0, "文件不存在");
                    return;
                }
                long fileSLength = file.length();
                DatagramSocket dataSocket = new DatagramSocket();
                //2,确定发送的具体的数据。
                FileInputStream in = new FileInputStream(filePath);
                byte[] buf = new byte[1024];
                int len;
                int sum = 0;
                while ((len = in.read(buf)) != -1) {
                    sum += len;
                    Log.e("message", "文件传输的大小==" + sum);
                    int progress = (int) (sum * 100 / fileSLength);
                    dataPacket = new DatagramPacket(buf, len, InetAddress.getByName(ip), port);
                    dataSocket.send(dataPacket);
                    updateProgress(progress);
                    Thread.sleep(10);  //延时一段时间,防止传输太快。丢包
                }
                if (dataPacket != null) {
                    dataSocket.close();
                }
                sendMessage(SendFileEntity.STATE_SUCCESS, 100, "发送成功");
            } catch (Exception e) {
                sendMessage(SendFileEntity.STATE_FAILED, 0, "发送失败:" + e.toString());
                Log.i("message", "发送文件异常:" + e.toString());
            }
        }
    
        int lsatProgress = 0;
    
        private void updateProgress(int progress) {
            if (progress > lsatProgress) {
                sendMessage(SendFileEntity.STATE_PROGRESS, progress, "发送中...");
                Log.e("message", "progress==" + progress);
            }
            lsatProgress = progress;
        }
    
        public void sendMessage(int state, int progress, String error) {
            SendFileEntity entity = new SendFileEntity(state, progress, error);
            EventBus.getDefault().post(entity);
        }
    
    }
    
    
    
    

    3:新建接收端的Runnable

      

    package com.example.administrator.canchatdemo.http;
    
    
    import android.content.Context;
    import android.util.Log;
    
    import com.example.administrator.canchatdemo.entity.ReceFileEntity;
    import com.example.administrator.canchatdemo.util.NetUtil;
    
    import org.greenrobot.eventbus.EventBus;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    
    /**
     * Created by Administrator on 2016/4/12.
     * 接受服务
     */
    
    public class MessageReceiveRunnable implements Runnable {
    
        private int port;
        //停止标志
        public static boolean flag;
    
        private DatagramSocket da = null;
    
        private Context context;
    
        public MessageReceiveRunnable(Context context, int port, boolean flag) {
            Log.i("message", "准备接受数据,开启线程");
            this.context = context;
            this.port = port;
            this.flag = flag;
        }
    
        public void run() {
    //        int state, int progress, String error
            sendMessage(ReceFileEntity.STATE_START, 0, "准备接收");
            try {
                if (da == null) {
                    da = new DatagramSocket(port);
                }
                String filePath = "/sdcard/zzz.mp4";
                File file = new File(filePath);
                if (file.exists()) {
                    file.delete();
                }
                file.createNewFile();
                FileOutputStream out = new FileOutputStream(filePath);
                Log.i("message", "接收消息的开关==" + flag);
                long sum = 0;
                int number = 0;
                while (flag) {
                    number++;
                    byte[] buf = new byte[1024];
                    DatagramPacket dp = new DatagramPacket(buf, buf.length);
                    da.receive(dp);
                    String ip = dp.getAddress().getHostAddress();
                    String data = new String(dp.getData(), 0, dp.getLength());
                    sum += buf.length;
                    sendMessage(ReceFileEntity.STATE_PROGRESS, sum, "接收中...");
                    Log.i("message", "==receiver===接受到了消息====ip=" + ip + "/" + sum + "/" + number);
                    out.write(buf);
                    if (!ip.contains(NetUtil.getLocalIp())) {
                        Log.i("message", "==receiver===接受到了别人发来的消息消息====ip=" + ip + "\ndata = " + data);
                    }
                }
            } catch (Exception e) {
                sendMessage(ReceFileEntity.STATE_FAILED, 0, e.toString());
                Log.i(e.getMessage(), "服务器挂了");
            } finally {
                try {
                    if (da != null)
                        da.close();
                } catch (Exception e) {
                    sendMessage(ReceFileEntity.STATE_FAILED, 0, e.toString());
                    e.printStackTrace();
                }
            }
        }
    
        public static void stopReceMessage() {
            flag = false;
        }
    
        public void sendMessage(int state, long progress, String error) {
            ReceFileEntity entity = new ReceFileEntity(state, progress, error);
            EventBus.getDefault().post(entity);
        }
    
    
    }
    


    4:获取IP的工具类

       

    package com.example.administrator.canchatdemo.util;
    
    import android.util.Log;
    import android.widget.Toast;
    
    import java.net.Inet4Address;
    import java.net.InetAddress;
    import java.net.NetworkInterface;
    import java.util.Enumeration;
    
    /**
     * Created by Administrator on 2016/4/14.
     * 定义常量
     */
    public class NetUtil {
        //定义端口
        public static final int PORT_ALL = 51000;
    
        //获取255ip
        public static String getIpToAll() {
            try {
                String ip = getLocalIp();
                if (ip == null)
                    return null;
                return getLocalIp().substring(0, 10) + "255";
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        //获取本地ip
        public static String getLocalIp() {
            try {
                for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
                    NetworkInterface intf = en.nextElement();
                    for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                        InetAddress inetAddress = enumIpAddr.nextElement();
                        if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
                            return inetAddress.getHostAddress().toString();
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    


    4:新建发送,接收的对象,用来更新界面

      

    package com.example.administrator.canchatdemo.entity;
    
    /**
     * UDP文件发送状态
     */
    
    public class SendFileEntity {
    
        int sendState;
        String desc;
        int progress;
    
        public static final int STATE_START = 0;
        public static final int STATE_PROGRESS = 1;
        public static final int STATE_SUCCESS = 2;
        public static final int STATE_FAILED = 3;
    
        public SendFileEntity(int sendState, int progress, String desc) {
            this.sendState = sendState;
            this.progress = progress;
            this.desc = desc;
        }
    
        public int getProgress() {
            return progress;
        }
    
        public void setProgress(int progress) {
            this.progress = progress;
        }
    
        public int getSendTate() {
            return sendState;
        }
    
        public void setSendTate(int sendState) {
            this.sendState = sendState;
        }
    
        public String getDesc() {
            return desc;
        }
    
        public void setDesc(String desc) {
            this.desc = desc;
        }
    
        @Override
        public String toString() {
            return "SendFileEntity{" +
                    "sendState=" + sendState +
                    ", desc='" + desc + '\'' +
                    ", progress=" + progress +
                    '}';
        }
    }
    


      5:另一个对象

           

    package com.example.administrator.canchatdemo.entity;
    
    /**
     * UDP文件接受状态
     */
    
    public class ReceFileEntity {
    
        int sendState;
        String desc;
        long progress;
    
        public static final int STATE_START = 0;
        public static final int STATE_PROGRESS = 1;
        public static final int STATE_SUCCESS = 2;
        public static final int STATE_FAILED = 3;
    
        public ReceFileEntity(int sendState, long progress, String desc) {
            this.sendState = sendState;
            this.progress = progress;
            this.desc = desc;
        }
    
        public long getProgress() {
            return progress;
        }
    
        public void setProgress(long progress) {
            this.progress = progress;
        }
    
        public int getSendTate() {
            return sendState;
        }
    
        public void setSendTate(int sendState) {
            this.sendState = sendState;
        }
    
        public String getDesc() {
            return desc;
        }
    
        public void setDesc(String desc) {
            this.desc = desc;
        }
    
        @Override
        public String toString() {
            return "SendFileEntity{" +
                    "sendState=" + sendState +
                    ", desc='" + desc + '\'' +
                    ", progress=" + progress +
                    '}';
        }
    }
    


    6:测试界面的代码 ,因为我是用自己的手机来发送 ,自己的手机来接收。需要的伙伴可以修改设备IP。用多台手机来测试,代码自己小改一下就可以了

    package com.example.administrator.canchatdemo;
    
    import android.app.Activity;
    import android.content.ComponentName;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.Bundle;
    import android.os.IBinder;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.ProgressBar;
    import android.widget.TextView;
    
    import com.example.administrator.canchatdemo.entity.ReceFileEntity;
    import com.example.administrator.canchatdemo.entity.SendFileEntity;
    import com.example.administrator.canchatdemo.service.SocketService;
    import com.example.administrator.canchatdemo.util.NetUtil;
    
    import org.greenrobot.eventbus.EventBus;
    import org.greenrobot.eventbus.Subscribe;
    import org.greenrobot.eventbus.ThreadMode;
    
    
    public class TestChatActiivty extends Activity implements View.OnClickListener {
    
        EditText et_content;
        Button button_send, btn_jump;
        TextView tv_ip;
    
        private SocketService service;
        private ServiceConnection conn = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder binder) {
                SocketService.MyBinder myBinder = (SocketService.MyBinder) binder;
                service = myBinder.getService();
                service.receiveMessage(TestChatActiivty.this, NetUtil.PORT_ALL);
    //            service.receiveFileMessage(NetUtil.PORT_ALL);
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
            }
        };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.test_main_chat);
            EventBus.getDefault().register(TestChatActiivty.this);
            initView();
        }
    
        TextView tv_send_state;
        TextView tv_send_progress;
        TextView tv_send_desc;
    
    
        TextView tv_rece_state;
        TextView tv_rece_progress;
        TextView tv_rece_desc;
    
    
        private void initView() {
            tv_send_state = (TextView) findViewById(R.id.tv_send_state);
            tv_send_progress = (TextView) findViewById(R.id.tv_send_progress);
            tv_send_desc = (TextView) findViewById(R.id.tv_send_desc);
    
            tv_rece_state = (TextView) findViewById(R.id.tv_rece_state);
            tv_rece_progress = (TextView) findViewById(R.id.tv_rece_progress);
            tv_rece_desc = (TextView) findViewById(R.id.tv_rece_desc);
    
    
            tv_ip = (TextView) findViewById(R.id.tv_ip);
            tv_ip.setText(NetUtil.getLocalIp());
            et_content = (EditText) findViewById(R.id.et_content);
            button_send = (Button) findViewById(R.id.button_send);
            button_send.setOnClickListener(this);
            btn_jump = (Button) findViewById(R.id.btn_jump);
            btn_jump.setOnClickListener(this);
        }
    
        String userIPToSend = "192.168.25.105";  //锤子
    
        // String userIPToSend = "192.168.25.114";  //小米
        @Override
        public void onClick(View view) {
            switch (view.getId()) {
                case R.id.btn_jump:
                    String content = getContent();
                    service.sendMessage(content, userIPToSend, NetUtil.PORT_ALL);
                    break;
                case R.id.button_send:
                    String filePath = "/sdcard/bbb.mp4";
                    service.sendFileMessage(filePath, userIPToSend, NetUtil.PORT_ALL);
                    break;
            }
    
        }
    
    
        @Subscribe(threadMode = ThreadMode.MAIN)
        public void sendFileNotify(SendFileEntity entity) {
            String stateShow = "";
            Log.i("down", "=====主界面消息==" + entity.toString());
            int state = entity.getSendTate();
            if (state == SendFileEntity.STATE_START) {
                stateShow = "准备发送";
            } else if (state == SendFileEntity.STATE_PROGRESS) {
                stateShow = "发送中";
            } else if (state == SendFileEntity.STATE_SUCCESS) {
                stateShow = "发送成功";
            } else if (state == SendFileEntity.STATE_FAILED) {
                stateShow = "发送失败";
            }
            tv_send_state.setText("发送状态===>" + stateShow);
            tv_send_progress.setText("发送进度===>" + entity.getProgress());
            tv_send_desc.setText("发送描述===>" + entity.getDesc());
        }
    
    
        @Subscribe(threadMode = ThreadMode.MAIN)
        public void sendFileNotify(ReceFileEntity entity) {
            Log.i("down", "=====主界面消息==" + entity.toString());
            int state = entity.getSendTate();
            String receState = "";
            if (state == ReceFileEntity.STATE_START) {
                receState = "准备接收";
            } else if (state == ReceFileEntity.STATE_PROGRESS) {
                receState = "接收中";
            } else if (state == ReceFileEntity.STATE_SUCCESS) {
                receState = "接收成功";
            } else if (state == ReceFileEntity.STATE_FAILED) {
                receState = "接收失败";
            }
            tv_rece_state.setText("接收状态===>" + receState);
            tv_rece_progress.setText("接收大小===>" + entity.getProgress());
            tv_rece_desc.setText("发送描述===>" + entity.getDesc());
        }
    
    
        public String getContent() {
            return et_content.getText().toString().trim();
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            Intent intent = new Intent(TestChatActiivty.this, SocketService.class);
            bindService(intent, conn, BIND_AUTO_CREATE);
        }
    
        @Override
        protected void onStop() {
            super.onStop();
            unbindService(conn);
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            EventBus.getDefault().unregister(TestChatActiivty.this);
        }
    }
    

    UI的xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
    
        <TextView
            android:id="@+id/tv_ip"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:gravity="center"
            android:text="ip"
            android:textColor="@color/myWhite"
            android:textSize="20sp" />
    
        <EditText
            android:id="@+id/et_content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="50dp"
            android:ems="10"
            android:inputType="textPersonName"
            android:text="Name"
            android:visibility="gone" />
    
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="发送的文件请放置根目录,命名请看代码" />
    
        <Button
            android:id="@+id/button_send"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:text="文件消息" />
    
    
        <Button
            android:id="@+id/btn_jump"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:text="文字消息"
            android:visibility="gone" />
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
    
            <TextView
                android:id="@+id/tv_send_state"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="发送状态===> 准备发送" />
    
            <TextView
                android:id="@+id/tv_send_progress"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="发送进度===> 30%" />
    
            <TextView
                android:id="@+id/tv_send_desc"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="发送进度===> 下载中..." />
    
        </LinearLayout>
    
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="50dp"
            android:orientation="vertical">
    
            <TextView
                android:id="@+id/tv_rece_state"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="接受状态===> 准备发送" />
    
            <TextView
                android:id="@+id/tv_rece_progress"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="接收进度===> 30%" />
    
            <TextView
                android:id="@+id/tv_rece_desc"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="接收进度===> 下载中..." />
    
        </LinearLayout>
    
    
    </LinearLayout>






































    展开全文
  • 比较TCP/UDP传输大文件时所用时间

    千次阅读 2019-05-03 16:43:24
    分别使用TCPUDP传输大文件,比较两者的传输时间。 二、实验目的 1.掌握TCPUDP的工作原理; 2.掌握TCP/UDP的简单代码实现方式; 三、实验内容 1.TCPClient核心代码 2.TCPServer核心代码 3.UDPClient核心代码 4...
  • TCPUDP文件传输分析

    千次阅读 2019-04-14 20:08:11
    题目要求 ... 分别使用TCPUDP协议,利用socket库,完成一个文件传输程序。 文本文件能够跨物理主机在局域网内进行传输。 语言不限(python,java,C,C++,C#)。 分析文件传输的时延。 分...
  • 利用TCP/UDP完成文件传输的设计和实现1) 利用循环面向连接的模型完成固定文件的传输(考虑服务器地址、端口号的设定方式) 2) 由固定文件扩展成手动输入或选择文件; 3) 参考connectTCP的方式对程序进行抽象、...
  • 浅析C#UDP传输大文件

    2019-11-07 18:14:29
    针对的是即便数据丢了几包也无所谓的情景,如果你非要这个传输大文件(如一个视频),我只能说你和我一样执着,明明该用TCP的,非要用UDP这个鬼东西……大概结果就是,你过去的东西打不开(中间有东西丢了你怎么...
  • QT网络编程—TCP一 QT网络编程—TCP二 QT网络编程--UDP QT网络编程---获取本机IP
  • 深入理解TCPUDP协议及两者的区别

    万次阅读 多人点赞 2018-11-14 13:03:24
    所谓的字节流服务(Byte Stream Service) 是指, 为了方便传输, 将块数据分割成以报文段(segment) 为单位的数据包进行管理。 而可靠的传输服务是指, 能够把数据准确可靠地给对方。 即TCP 协议为了更容易...
  • Udp传大文件问题

    千次阅读 2014-10-29 16:37:07
    Udp传文件和长字符串,需要分批,但是Udp不是面向连接的,服务端接收文件,如果多个客户端都在往该服务器传文件,不知道是哪个客户端发送过来的,那怎么才能正确判断是哪个客户端发过来的,把过来的文件数据包存储到...
  • 网络C/S文件传输工具,支持`UDP/TCP`,断点续,局域网探测,上传下载,文件校验: 上传命令: $ file put //参数支持-分割,也可直接输入 $ file -put //第三参数为空时,默认TCP上传方式 $ file put -tcp //...
  • Java 使用 TCPUDP 传输文件
  • udp传输大文件的一个例子

    万次阅读 2016-08-11 16:18:04
    服务器server.c /************************************************************************* > File Name: server.c > Author: ljh ********************************************************************
  • [代码笔记] python 之网络编程: 使用udp 发送音频文件 超时重: Python3.x:简单时间调度Timer(间隔时间执行) vscode使用: 非常全的VsCode快捷键 python全局变量与局部变量: Python语法基础——关于全局...
  • 网络传输方式-UDPTCP

    2019-05-27 12:20:49
    UDP:英文全拼(User Datagram Protocol)简称用户数据报协议,它是无连接的、不可靠的网络传输协议。udp网络传输协议好比现实生活中写信。 1.1 UDP特点 因为udp发送数据之前不需要建立连接所有具有以下特点 无连接 ...
  • 开发即时通信是选择UDP还是TCP协议

    千次阅读 2015-10-29 07:44:57
    使用UDP协议和规模即时通讯的思考  之前做过局域网的聊天软件,现在要做运行在广域网的聊天软件。开始接触网络编程,首先是接触到TCPUDP协议 在网上查资料,都是这样描述 TCP面向连接,可靠,数据流 。...
  • DNS用UDP还是TCP传输

    千次阅读 2015-08-27 20:04:31
    当客户端发出DNS查询请求,从服务器收到的响应报文中的TC(删减标志)比特被置为1时,表示应答总长度超过512字节,只返回前512个字节,这时DNS就需要使用TCP重发原来的查询请求。因为在UDP的应用程序中,其应用程序...
  • 为什么视频用udp不用tcp

    千次阅读 2016-08-17 11:57:22
    当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数 据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端到另一端。   UDP---用户数据报协议,是...
  • Windows Socket编程之UDP实现大文件传输

    千次阅读 热门讨论 2017-04-30 13:55:56
    TCP版本请参考本人博客:http://blog.csdn.net/luchengtao11/article/details/71012580本文所述代码工程托管在Github:https://github.com/Wuchenwcf/MyCode/tree/master/C%2B%2B/Socket本文实现以下功能:在客户端,...
  • 分析QQ微信使用的是UDP还是TCP协议

    千次阅读 2020-05-02 22:18:41
    首先需要明白TCP UDP各自的概念以及区别 tcp: 传输控制协议,全拼:Transmission Control Protocol 它是一个面向连接,可靠的传输协议 ...tcpudp都是传输层的两个传输协议 tcp的特点: 4.1 面向连接,间接验证对方ip...
  • Socket内部又有两种协议(Tcp/Udp),我们来说说其各自的特点。先来说说网络编程的三要素1.IP地址:网络中计算机的唯一标识 2.端口 3.协议:通信的规则 Tcp/Udp特点一、 TCP(协议): 建立连接,形成传输数据的通道 ...
  • 2) 基于Java Socket TCPUDP实现一个简易的网络文件服务程序,包含服务器端FileServer和客户端FileClient; 3) 服务器端启动时需传递root...7) 服务器端支持多用户并发访问,不用考虑文件UDP传输不可靠的问题。
  • 在信息技术与互联网技术快速发展的今天,很多企业,特别是大中型企业都建设了林林总总的信息...实现文件传输的方式有很多,FTP无疑是应用最广的一种方式,但在大数据时代下,Raysync协议更能满足传输大文件的要求。...
  • UDP/TCP网络传输方式

    千次阅读 2018-09-04 16:04:09
    网络传输方式 1.面向无连接型:  不要求建立和断开连接,发送端可于任何时候自由发送数据. 反之, 接收端也永远不知道自己会在何时从那里接收到数据. 因此, 面向无连接的情况下, 接收端需要时常确认是否收到了数据...
  • Qt 中使用UDP传送图片(文件)的方法

    千次阅读 热门讨论 2017-10-17 22:34:26
    我们知道传送文件一般使用的是TCP,要是需要使用UDP应该怎么做呢?  对于发端,首先应该在点击事件中得到我们需要发送的文件名,这里是fileName。得到名字之后,新建一个QFile类,来存自己的QFIle文件。每次读8000...
  • DNS的是TCP协议还是UDP协议 DNS 查询以各种不同的方式进行解析。客户机有时也可通过使用从以前查询获得的缓存信息就地应答查询。DNS 服务器可使用其自身的资源记录信息缓存来应答查询,也可代表请求客户机来查询...
  • DNS使用TCP还是UDP协议

    2016-09-27 19:51:00
    本文转自:http://benbenxiongyuan.iteye.com/blog/1088085DNS同时占用UDPTCP端口53是公认的,这种单个应用协议同时使用两种传输协议的情况在TCP/IP栈也算是个另类。但很少有人知道DNS分别在什么情况下使用这两种...
  • TCPUDP传输方式对比

    千次阅读 2019-05-09 10:57:45
    UDP传输方式 UDP (User Datagram Protocol )用户数据报协议,是一种面向无连接的传输方式,不提供复杂的控制机制, 如果传输过程中出现丢包, UDP 也不负责重发. 甚至当出现包到达顺序乱掉时候也没有纠正的功能. 由于...

空空如也

1 2 3 4 5 ... 20
收藏数 257,445
精华内容 102,978
关键字:

udp 大文件下载