千家信息网

socket文件传输功用的完成

发表于:2024-11-25 作者:千家信息网编辑
千家信息网最后更新 2024年11月25日,这节我们来完成 socket 文件传输程序,这是一个十分适用的例子。要完成的功用为:client 从 server 下载一个文件并保管到当地。编写这个程序需求留意两个成绩:1) 文件巨细不肯定,有能够
千家信息网最后更新 2024年11月25日socket文件传输功用的完成

这节我们来完成 socket 文件传输程序,这是一个十分适用的例子。要完成的功用为:client 从 server 下载一个文件并保管到当地。
编写这个程序需求留意两个成绩:
1) 文件巨细不肯定,有能够比缓冲区大许多,挪用一次 write()/send() 函数不克不及完成文件内容的发送。接纳数据时也会碰到异样的状况。
要处理这个成绩,可以运用 while 轮回,例如:

                    //Server 代码 int nCount; while( (nCount = fread(buffer, 1, BUF_SIZE, fp)) > 0 ){ send(sock, buffer, nCount, 0); } //Client 代码 int nCount; while( (nCount = recv(clntSock, buffer, BUF_SIZE, 0)) > 0 ){ fwrite(buffer, nCount, 1, fp); }

关于 Server 端的代码,当读取到文件末尾,fread() 会前往 0,完毕轮回。
关于 Client 端代码,有一个症结的成绩,就是文件传输终了后让 recv() 前往 0,完毕 while 轮回。

留意:读取完缓冲区中的数据 recv() 并不会前往 0,而是被壅塞,直到缓冲区中再次无数据。

2) Client 端若何判别文件接纳终了,也就是下面提到的成绩--何时完毕 while 轮回。
最复杂的完毕 while 轮回的办法当然是文件接纳终了后让 recv() 函数前往 0,那么,若何让 recv() 前往 0 呢?recv() 前往 0 的独一机遇就是收到FIN包时。
FIN 包表现数据传输终了,盘算机收到 FIN 包后就晓得对方不会再向本人传输数据,当挪用 read()/recv() 函数时,假如缓冲区中没无数据,就会前往 0,表现读到了"socket文件的末尾"。
这里我们挪用 shutdown() 来发送FIN包:server 端直接挪用 close()/closesocket() 会使输入缓冲区中的数据生效,文件内容很有能够没有传输终了衔接就断开了,而挪用 shutdown() 会等候输入缓冲区中的数据传输终了。
本节以Windows为例演示文件传输功用,Linux与此相似,不再赘述。请看下面完好的代码。
效劳器端 server.cpp:

                  #include  #include  #include  #pragma comment (lib, "ws2_32.lib") //加载 ws2_32.dll #define BUF_SIZE 1024 int main(){ //先反省文件能否存在 char *filename = "D:\\send.avi"; //文件名 FILE *fp = fopen(filename, "rb"); //以二进制方法翻开文件 if(fp == NULL){ printf("Cannot open file, press any key to exit!\n"); system("pause"); exit(0); } WSADATA wsaData; WSAStartup( MAKEWORD(2, 2), &wsaData); SOCKET servSock = socket(AF_INET, SOCK_STREAM, 0); sockaddr_in sockAddr; memset(&sockAddr, 0, sizeof(sockAddr)); sockAddr.sin_family = PF_INET; sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); sockAddr.sin_port = htons(1234); bind(servSock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR)); listen(servSock, 20); SOCKADDR clntAddr; int nSize = sizeof(SOCKADDR); SOCKET clntSock = accept(servSock, (SOCKADDR*)&clntAddr, &nSize); //轮回发送数据,直到文件开头 char buffer[BUF_SIZE] = {0}; //缓冲区 int nCount; while( (nCount = fread(buffer, 1, BUF_SIZE, fp)) > 0 ){ send(clntSock, buffer, nCount, 0); } shutdown(clntSock, SD_SEND); //文件读取终了,断开输入流,向客户端发送FIN包 recv(clntSock, buffer, BUF_SIZE, 0); //壅塞,等候客户端接纳终了 fclose(fp); closesocket(clntSock); closesocket(servSock); WSACleanup(); system("pause"); return 0; }


客户端代码:

                    #include  #include  #include  #pragma comment(lib, "ws2_32.lib") #define BUF_SIZE 1024 int main(){ //先输出文件名,看文件能否能创立胜利 char filename[100] = {0}; //文件名 printf("Input filename to save: "); gets(filename); FILE *fp = fopen(filename, "wb"); //以二进制方法翻开(创立)文件 if(fp == NULL){ printf("Cannot open file, press any key to exit!\n"); system("pause"); exit(0); } WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); sockaddr_in sockAddr; memset(&sockAddr, 0, sizeof(sockAddr)); sockAddr.sin_family = PF_INET; sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); sockAddr.sin_port = htons(1234); connect(sock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR)); //轮回接纳数据,直到文件传输终了 char buffer[BUF_SIZE] = {0}; //文件缓冲区 int nCount; while( (nCount = recv(sock, buffer, BUF_SIZE, 0)) > 0 ){ fwrite(buffer, nCount, 1, fp); } puts("File transfer success!"); //文件接纳终了后直接封闭套接字,无需挪用shutdown() fclose(fp); closesocket(sock); WSACleanup(); system("pause"); return 0; }

在D盘中预备好send.avi文件,先运转 server,再运转 client:
Input filename to save: D:\\recv.avi↙
//稍等少焉后
File transfer success!
翻开D盘就可以看到 recv.avi,巨细和 send.avi 相反,可以正常播放。
留意 server.cpp 第42行代码,recv() 并没有接纳到 client 端的数据,当 client 端挪用 closesocket() 后,server 端会收到FIN包,recv() 就会前往,前面的代码持续履行。


文件 数据 传输 代码 缓冲区 缓冲 成绩 函数 客户 客户端 文件名 输入 功用 二进制 内容 就是 巨细 数据传输 方法 末尾 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 通讯企业软件开发工资 网络安全征文350字左右 广州拓晟互联网科技有限公司 数据库及其应用批发 泰安易事通股票软件开发公司 无锡营销网络技术收费标准 telnet服务器的端口 客服数据库mysql 华文网络技术有限公司招聘 数据库五十到九十之间 客户服务器数据库体系特点 扬州通信网络技术管理系统 翱翔网络技术有限公司 手机作为服务器ip如何映射 宝马七系车网络技术 厦门直播软件开发运营需要多少钱 如何将数据写入数据库 web服务器安全方法 污染源企业信息的数据库表 顺丰科技的互联网运维转型之路 如何给数据库贴代码 服务器与网络管理 技术做保险系统数据库结构图 网络安全国家标准案例 软件开发中的数据存储 rsyslogd-n服务器宕机 服务器必须要的几个指令 传真安全还是网络安全 婚纱店的数据库 九台区正规网络技术咨询哪家好
0