C语言socket实现文件下载
程序员文章站
2022-05-21 10:56:12
是网络的作业,我比较菜。写到定位输出,做百分比出现了问题,不显示0到100的,直接从0跳到了100。请教了下大佬。改了过来。原来是类型的问题,做出来的运算应该是float,但是我都定义的int,输出...
是网络的作业,我比较菜。写到定位输出,做百分比出现了问题,不显示0到100的,直接从0跳到了100。请教了下大佬。改了过来。原来是类型的问题,做出来的运算应该是float,但是我都定义的int,输出也是,大佬指出后,我好尴尬。犯了小错误。但是在这次过程也学习了一波。要加油了!代码写的这么乱!
写的是带颜色的版本,颜色有可能会觉得妖艳,好吧。
编译平台是++6.0
还是有点bug,有时,客户端发dir命令时会退出。有空再看看。这几天太忙。萌新的我只会点c,不会c++。如有错误,望大佬指出。谢谢。
sever:
#include #include #include #include #include #include #include #pragma comment(lib,"ws2_32.lib") using namespace std; #define default_buflen 512 #define default_port 8088 #define buffer_size 4096 char sendbuffer[buffer_size],recvbuffer[buffer_size]; //发送缓冲区及接收缓冲区 socket acceptsocket; dword winapi clientthread(lpvoid lp); struct clientinfo{ socket clientsocket; sockaddr_in sockaddr; }; int main(int argc, tchar* argv[]) { int ret; wsadata wsadata; if((ret = wsastartup(makeword(2,2),&wsadata)) != no_error) { printf("wsastartup failed with error %d\n",ret); return -1; }//if // create a new socket to listening for client connections. socket listensocket; if((listensocket = socket(af_inet,sock_stream,ipproto_tcp)) == invalid_socket) { printf("socket failed with error %d\n",wsagetlasterror()); wsacleanup(); return -1; }//if sockaddr_in service; service.sin_family = af_inet; service.sin_addr.s_addr = inet_addr("127.0.0.1"); service.sin_port = htons(default_port); if(bind(listensocket,(sockaddr* ) &service,sizeof(service)) == socket_error) { printf("bind failed with error %d\n",wsagetlasterror()); closesocket(listensocket); wsacleanup(); return -1; }//if if(listen(listensocket, 10) == socket_error) { printf("error listening on socket.\n"); closesocket(listensocket); wsacleanup(); return -1; }//if socket acceptsocket; sockaddr_in clientaddr;//接收客户端地址 int addrclientlen = sizeof(clientaddr); while(true) { clientinfo clientinfo; printf("waiting for client to connect......\n"); acceptsocket = accept(listensocket,(sockaddr* ) &clientaddr, &addrclientlen); if(acceptsocket == invalid_socket) { printf("accept failed : %d\n",wsagetlasterror()); closesocket(listensocket); wsacleanup(); return 1; }//if clientinfo.clientsocket = acceptsocket; memcpy(&clientinfo.sockaddr,&clientaddr,sizeof(sockaddr_in)); printf("a client is coming......\n"); dword dwthreadid; createthread(null,0,clientthread,(lpvoid* )&clientinfo,0,&dwthreadid); }//while closesocket(listensocket); wsacleanup(); return 0; } //main dword winapi clientthread(lpvoid lp) { clientinfo *pclientinfo = (clientinfo* )lp; socket clientsocket = pclientinfo->clientsocket; sockaddr_in sockaddr; memcpy(&sockaddr,&pclientinfo->sockaddr,sizeof(sockaddr_in)); int iresult,bytes; char recvrfilename[default_buflen] = ""; char temp_buffer[buffer_size]; unsigned readlen; dword dwreadsize = 0; char curpath[max_path]; char quit [10] ="quit"; //获得相对路径 getmodulefilename(null,(lpstr)curpath,sizeof(curpath)); strrchr( curpath, '\\')[0]= 0; ifstream infile; while(true) { memset(recvrfilename,0,sizeof(recvrfilename)); iresult = recv(clientsocket,recvrfilename,default_buflen,0); if(socket_error == iresult) { printf("recvieve failed with error : %d\n",wsagetlasterror()); closesocket(clientsocket); wsacleanup(); return -1; }//if //命令有get help exit -s(文件大小) //help char dir [10] ="dir"; char get [10] ="get"; printf("传过来的数据:%s",recvrfilename); if(strcmp(recvrfilename,dir)==0){ //返回命令 system("cmd /c dir /a-d /b >allfiles.txt"); printf("查看allfiles文件\n"); //将打印出来的文件信息读取出来 file *file; char buf[1024]; int len=0,i=0; char *array[1024]; char filedir [1024];//要传过去的文件目录 file=fopen("allfiles.txt","r");//打开txst.txt文件 if(!file)return -1; while(fgets(buf,1024,file))//读取txt中字符 { len=strlen(buf); array[i]=(char*)malloc(len+1); if(!array[i])break; strcpy(array[i++],buf); }//while fclose(file); i--; while(i>=0&&array[i]) { printf("%s\n",array[i]);//打印test文档的字符 iresult = send(clientsocket,array[i],strlen(array[i]),0); if(iresult==socket_error){printf("发送失败\n");} free(array[i--]); }//while printf("发送结束quit\n"); send(clientsocket,quit,strlen(quit),0); continue; }//if //完整文件名 strcat(curpath,"\\"); strcat(curpath,recvrfilename); strcpy( recvrfilename,curpath); //获取文件大小 file * pfile; long size; pfile = fopen (recvrfilename,"rb"); if (pfile==null) perror ("error opening file"); else { fseek (pfile, 0, seek_end); ///将文件指针移动文件结尾 size=ftell (pfile); ///求出当前文件指针距离文件开始的字节数 fclose (pfile); printf ("filesize : %ld bytes.\n",size); char a[30]; //将size保存在字符串a中 sprintf(a,"%d",size); send(clientsocket, a, 30, 0); printf("发送文件大小:%s",a); } printf("文件:%s\n",recvrfilename); infile.open(recvrfilename,ios::in|ios::binary); if(!infile) { //未成功打开文件 printf("sorry, cannot open %s. please try again.\r\n",recvrfilename); //break; }//if else { printf("the file %s is found,ready to transfer.\n",recvrfilename); printf("transfering\r\n"); while (!infile.eof()) { //循环读取文件并通过h_newsocket发送到客户端 //printf(sendbuffer,"%s",temp_buffer); infile.read(sendbuffer,buffer_size); readlen = infile.gcount(); send(clientsocket, sendbuffer, readlen, 0); //printf("."); } infile.close(); printf("transfer completed... \r\n"); //bytes = send(acceptsocket, sendbuffer, strlen(sendbuffer), 0); }//else //如果没有数据发送 iresult = shutdown(clientsocket,sd_both); if (iresult == socket_error) { printf("shutdown failed: %d\n", wsagetlasterror()); }//if closesocket(clientsocket); return 0; }//while }//main
client:
#include #include #include #include #include #include #include using namespace std; #pragma comment(lib,"ws2_32.lib") #define default_buflen 512 #define default_port 5150 #define buffer_size 4096 int main(int argc, tchar* argv[]) { int iresult,rec; wsadata wsadata; handle hout; ofstream outfile; socket connectsocket = invalid_socket; struct sockaddr_in clientservice; char sendbuf[default_buflen] = ""; char szbuffer[buffer_size]; bool issend = true; //初始化windows sockets dll if(iresult = wsastartup(makeword(2,2),&wsadata) != no_error) { printf("wsastartup failed with error : %d\n",iresult); return -1; } //创建socket connectsocket = socket(af_inet,sock_stream,ipproto_tcp); if(connectsocket == invalid_socket) { printf("socket failed with error : %d\n",wsagetlasterror()); wsacleanup(); return -1; } //////////////////// char addr[20]; int prot ; printf("现在运行的是客户端!\n"); printf("**************************************************************\n"); printf("请输入服务器的ip地址:"); scanf("%s",addr); printf("请输入服务器的端口:"); scanf("%d",&prot); /////////////////// //设置目的网络地址并连接服务器 clientservice.sin_family = af_inet; clientservice.sin_addr.s_addr = inet_addr(addr); clientservice.sin_port = htons(prot); iresult = connect(connectsocket,(sockaddr* )&clientservice,sizeof(clientservice)); if(iresult == socket_error) { printf("connect failed with error : %d\n",wsagetlasterror()); closesocket(connectsocket); wsacleanup(); return -1; } printf("connect with server successfully!!!\n"); hout = getstdhandle(std_output_handle); setconsoletextattribute(hout, foreground_green); cout<<"输入命令:******************* help 获取命令提示**********************:\n"; while(true) { //输入命令: char cmd [20]; char help [10] ="help"; char exit [10] ="exit"; char get [10] ="get"; char dir [10] ="dir"; char quit [10] ="quit"; scanf("%s",&cmd); printf("输入的命令是%s\n",cmd); if(strcmp(cmd,help)==0){ printf("命令参数:\n help----------获取命令帮助\n dir----------获取文件目录\n get----------下载文件\n exit----------退出\n"); continue; } // 列目录 if(strcmp(cmd,dir)==0){ iresult = send(connectsocket,dir,strlen(dir),0); if(socket_error == iresult) { printf("send failed with error : %d\n",wsagetlasterror()); closesocket(connectsocket); wsacleanup(); return -1; } //接收传过来的目录 setconsoletextattribute(hout, foreground_green | foreground_blue); printf("**********************文件目录**********************\n"); char dirs [30]; while(true){ zeromemory(dirs,30); iresult = recv(connectsocket,dirs,30,0); //数据发送完成就跳出循环,结束时,服务器发过来quit if(strcmp(dirs,quit)==0){break;} else printf("%s\n",dirs); if(socket_error == iresult) { printf("recvieve failed with error : %d\n",wsagetlasterror()); closesocket(connectsocket); wsacleanup(); return -1; }//if //接收完再次返回 // continue; }//while continue; }//if if(strcmp(cmd,exit)==0){break;} if(strcmp(cmd,get)==0){ setconsoletextattribute(hout, foreground_intensity | foreground_red); printf("您输入的命令是get,下载文件,请依次输入要下载的文件名、保存本地文件名\n"); //文件下载 参数get后使用 char str[20]; //文件名 scanf("%s",&str); zeromemory(sendbuf,default_buflen); strcpy(sendbuf,str); if(strcmp(str,quit)==0){ printf("您输入了exit,退出get\n"); continue; } setconsoletextattribute(hout, foreground_red | foreground_green | foreground_blue); iresult = send(connectsocket,sendbuf,strlen(sendbuf),0); if(socket_error == iresult) { printf("send failed with error : %d\n",wsagetlasterror()); closesocket(connectsocket); wsacleanup(); return -1; } //接收文件总大小 int size; char sizestr [30]; recv(connectsocket,sizestr,30,0); size = strtol (sizestr,null,10); setconsoletextattribute(hout, foreground_blue | foreground_red); printf("总的数据大小:%ld\n",size); //cout<<"输入存放文件(路径+文件名):\n"; char cfilename[default_buflen] = ""; scanf("%s",&cfilename); setconsoletextattribute(hout, foreground_intensity|foreground_red|foreground_blue|foreground_green ); printf("保存文件:%s\n",cfilename); outfile.open(cfilename,ios::out|ios::binary); if(!outfile) //打开文件准备写入 { printf("error of opening file !"); iresult = shutdown(connectsocket, sd_send); iresult = closesocket(connectsocket); wsacleanup(); return -1; } coord coord; console_screen_buffer_info csbi; hout=getstdhandle(std_output_handle); getconsolescreenbufferinfo(hout,&csbi); coord.x =csbi.dwcursorposition.x; coord.y =csbi.dwcursorposition.y; float cnt = 0; while(issend) { //读取流 rec = recv(connectsocket,szbuffer,buffer_size,0); cnt+=rec; if(rec == 0) { setconsoletextattribute(hout, foreground_intensity | foreground_red); printf("download completed ! \n"); break; } else if(rec == socket_error) { printf("receive function failed with error : %d\n ",wsagetlasterror()); break; } setconsolecursorposition(hout,coord); setconsoletextattribute(hout, foreground_intensity | foreground_green); printf("received %f%% bytes \n",cnt/size*100); outfile.write(szbuffer,rec); } setconsoletextattribute(hout, foreground_intensity | foreground_blue); printf("transfer is completed!\n"); setconsoletextattribute(hout, foreground_intensity|foreground_red|foreground_blue|foreground_green ); outfile.close(); } // 若没有数据要发送,单向关闭连接 iresult = shutdown(connectsocket, sd_send); // step 6: 关闭连接 iresult = closesocket(connectsocket); wsacleanup(); return 0; } }
效果:
上一篇: C语言编写扫雷