• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > C++文件上传、下载工具

C++文件上传、下载工具

作者:逍遥天下1688 字体:[增加 减小] 来源:互联网 时间:2017-05-28

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



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 深入理解C++中的文件操作
  • C++文件上传、下载工具
  • 深入分析C++中执行多个exe文件方法的批处理代码介绍
  • C++文件依存关系介绍

相关文章

  • 2017-05-28C语言中#define与typedef的互换细节详解
  • 2017-05-28C#中委托的基本用法总结
  • 2017-05-28DSP中浮点转定点运算--定点数的加减乘除运算
  • 2017-05-28C语言编程中的联合体union入门学习教程
  • 2017-05-28深入理解C/C++混合编程
  • 2017-05-28C++中求余运算符(%)示例详解
  • 2017-05-28解析C++编程中如何使用设计模式中的状态模式结构
  • 2017-05-28linux c多线程编程实例代码
  • 2017-05-28java 中ArrayList与LinkedList性能比较
  • 2017-05-28MySQL的C语言API接口

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C语言中多维数组的内存分配和释放(malloc与free)的方法
    • 深入解析C++中的字符数组和处理字符串的方法
    • C语言中const,volatile,restrict的用法总结
    • C语言指针变量的运算(加法、减法和比较运算)
    • c++判断是否为目录的示例分享
    • CString,字符串,整数等相互转换方法(推荐)
    • C++中运算符 &和&&、|和|| 的详解及区别
    • C++实现读取特定路径下文件夹及文件名的方法
    • 显示内存状态示例分享
    • 浅谈Windows系统下C语言编程中Glib库的使用

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有