逍遥天下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

