逍遥天下1688 通过本文主要向大家介绍了如何编译c++文件,c++怎么输文件名,c++ 二进制文件,c++文件读写,c++文件输入输出等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com
本文实例为大家分享了C++文件上传下载的实现代码,供大家参考,具体内容如下
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/timeb.h> #include <sys/ioctl.h> #include <string.h> #include <fcntl.h> #include <sys/wait.h> #include <sys/socket.h> #include <errno.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <netinet/in.h> #include <netinet/tcp.h> #include <arpa/inet.h> #ifndef __TCPFILE_C__ #define __TCPFILE_C__ #include "libfunc.h" #include "vapi_log.h" #define CMDHEAD 6 // 通信报文头信息长度 #define CMDINFO 6 // 空值命令 PUT GET #define CMD #define MAXKB 16 #define NCMD 32 #define NFILE 128 // tcp 通信命令行缓冲区 typedef struct tcpCmd { int len; // 命令行长度 char cmd[NCMD+1]; // 命令行缓冲区 } tcpCmd; struct tcpBuffer { int rlen; // 接收数据长度 int wlen; // 发送数据长度 char rcvcmd[NCMD+1]; // 接收命令域数据 char sndcmd[NCMD+1]; // 接收命令域数据 tcpCmd rCmd ; // 接收缓冲区 tcpCmd sCmd ; // 发送缓冲区 char buff[1024 * MAXKB + 64 + 1 ]; // 报文缓冲区, 包含命令控制串和实际报文数据 } ncb; // ////////////////////////////////////////////////////////////////////////////////////////////// //// // // // 根据报文头数据要求,接收一个通信数据。 // // 程序首先按照要求读取 headlen 长度的长度包数据,然后再次从网络上读取真正长度的数据包。 // // // // 数据接收函数分两次进行处理,返回数据 sData 中已经不再包含 6位通信长度数据。 // // ///////////////////////////////////////////////////////////////////////////////////////////// //// int tcp_readbuf(int headlen, int sfd, char * sData, int MaxLen, int sTime) { int iRet = 0; int left_bytes, thisRead, sLen; char *ptr = sData; struct timeval tv; fd_set rfds; char temp[ NCMD + 1 ]; tv.tv_sec = (long )sTime ; tv.tv_usec = 0; FD_ZERO(&rfds); FD_SET(sfd, &rfds); do{ iRet = select(sfd+1, &rfds, NULL, NULL, &tv) ; }while (iRet < 0 && errno == EINTR ); if(iRet == 0){ wLog(LOGERROR,"tcp_readbuf select 延时[%d] 结束, faile [%d, %s]", sTime, errno, strerror(errno) ); return -1; } // 接受控制命令序列 memset(temp, 0x00 , sizeof (temp)); thisRead = read(sfd, temp, headlen); if( temp[0]=='0' )sLen = atoi(temp); else sLen = 0; if(thisRead != headlen && sLen ){ wLog(LOGERROR,"读取通信报文长度[%s]失败, faile [%d, %s]", temp, errno, strerror(errno) ); return -1; } if(sLen < 1 || sLen > MaxLen ){ if(sLen > MaxLen ) wLog(LOGERROR,"报文长度[%s]错误,数据非法. ", temp ); return -1; } left_bytes = sLen; while( left_bytes > 0 ){ if( (thisRead = read(sfd, ptr, left_bytes)) == 0) break ; if(thisRead < 0 ){ if( errno == EINTR ) continue; break; } left_bytes -= thisRead; ptr += thisRead; } if(left_bytes && ptr != sData ) wLog(LOGERROR,"[tcp_readbuf [%d] faile [%d, %s]", sLen, errno, strerror(errno) ); /* 数据没有处理完时,程序打印错误日志信息 */ return(sLen-left_bytes); } // // 数据发送程序,在指定的延时内将指定长度的数据包发送到 sfd 上。 // 发送数据需要将报文长度保存在 sData 中,发送长度比实际的报文多出长度域 6字节 // int tcp_writebuf(int sfd, char * sData, int sLen, int sTime) { int iRet = 0; int left_bytes, thisWrite; char *ptr = sData; fd_set wfds; struct timeval tv; FD_ZERO(&wfds); FD_SET(sfd, &wfds); do{ iRet = select(sfd+1, NULL, &wfds, NULL, &tv) ; }while (iRet < 0 && errno == EINTR ); if(iRet==0){ wLog(LOGERROR,"tcp_writebuf select 延时[%d] 结束, faile [%d, %s]", sTime, errno, strerror(errno) ); return -1; } // 检查通信链路的 写状态 left_bytes=sLen; while(left_bytes >0 ){ if( (thisWrite = write(sfd, ptr, left_bytes)) == 0) break ; if(thisWrite < 0 ){ if( errno == EINTR ) continue; break; } left_bytes -= thisWrite; ptr += thisWrite; } // 将数据发送到通信端口 if(left_bytes && ptr != sData ) wLog(LOGERROR,"[tcp_sendbuf left_bytes[%d] faile [%d, %s]", left_bytes, errno, strerror(errno) ); return(sLen-left_bytes); } // ============================= 客户端使用 文件发送程序 ================================= //// // // // socket 方式文件发送程序,根据输入的 netinfo 建立通信通道,然后按照以下要求发送文件 // // PUT100 发送文件基本信息 // // PUT200 发送文件内容,根据要求循环执行,...... // // PUT300 数据发送结束 // // // // ======================================================================================= //// int cli_put_sendFile(char *netinfo, char *localFile, char *remoteFile, int blockSize, int timeout) { int sfd, fd; struct stat sb; int iRet ; int chkflg = 0 ; int maxBlk, blknum = 0; long start; long fsize; sfd = fd = -1; start = time(NULL); sfd = make_tcpConnect (netinfo); // 申请 socket 描述符,使用 connect () 建立到服务器的连接通道 if(sfd < 0 ) { wLog(LOGERROR,"建立到[%s]连接失败 error [%d, %s]", netinfo , errno, strerror(errno) ); return -4; } wLog(LOGINFO, "成功建立到[%s]发送通道[%d]", netinfo, sfd ); fd = open(localFile, O_RDONLY); if(fd == -1){ wLog(LOGERROR,"本地文件[%s]打开失败 error [%d, %s]", localFile , errno, strerror(errno) ); close (sfd ); return -3; } if (fstat(fd, &sb) < 0) { wLog(LOGERROR,"取[%s]文件信息失败 error [%d, %s]", localFile , errno, strerror(errno) ); chkflg = -3; goto cli_put_sendFile_END; } fsize = sb.st_size; if(blockSize > 1024 * MAXKB ) blockSize = 1024 * MAXKB ; if(blockSize < 1024 ) blockSize = 1024; // 显示本地文件的基本信息 wLog(LOGINFO, "成功打开本地文件[%s], size[%ld] ", localFile, fsize ); maxBlk = (int ) ( (fsize ) / blockSize) ; // 计算本文件的最大传输次数 if( fsize % blockSize ) maxBlk += 1; // 不足整块的数据,需要按一块进行处理。 memset(&ncb , 0x00 , sizeof (struct tcpBuffer)); // 准备发送文件控制命令串, 告诉对方准备发送文件的基础信息 ncb.wlen = snprintf(ncb.buff+25, sizeof(ncb.buff)-1, "%s:%010ld:%010d:%010d", remoteFile, fsize , blockSize , maxBlk ); sprintf(ncb.sndcmd , "%06d%-16s%1s%2s", ncb.wlen+19, "PUT100FILEINFO", "1", "00"); memcpy(ncb.buff, ncb.sndcmd, 25); ncb.wlen += 25; iRet = tcp_writebuf (sfd , ncb.buff, ncb.wlen, timeout); if(iRet != ncb.wlen){ wLog(LOGERROR,"发送[%d] [%s]失败 error [%d, %s]", ncb.wlen, remoteFile , errno, strerror(errno) ); chkflg = -2; goto cli_put_sendFile_END; } wLog(LOGINFO,"发送报文头[%d] [%s]成功", ncb.wlen , ncb.buff ); ncb.rlen = tcp_readbuf(6, sfd, ncb.rcvcmd , 19, timeout); if(ncb.rlen != 19 || memcmp(ncb.rcvcmd+17, "00", 2)){ wLog(LOGERROR,"远程保存[%s]失败 error [%d, %s]", remoteFile , errno, strerror(errno) ); chkflg = -2; goto cli_put_sendFile_END; } wLog(LOGINFO,"接到返回数据 [%s]成功", ncb.rcvcmd ); // 循环将本地文件全部发送完毕 while ( 1 ){ blknum ++; memset(&ncb , 0x00 , sizeof (struct tcpBuffer )); ncb.rlen = read (fd, ncb.buff+25, blockSize ); if(ncb.rlen < 1 ) break ; // 本地文件已经发送结束 sprintf (ncb.sndcmd , "%06dPUT200BLK%07d%1s%2s", ncb.rlen+19, blknum, "1", "00"); memcpy(ncb.buff, ncb.sndcmd , 25); ncb.rlen += 25; iRet = tcp_writebuf (sfd , nc