• 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++ socket实现miniFTP

C++ socket实现miniFTP

作者:ZJU_fish1996 字体:[增加 减小] 来源:互联网 时间:2017-05-28

ZJU_fish1996 通过本文主要向大家介绍了miniftp,miniftpserver,c++ socket,c++ socket网络编程,c++ socket编程实例等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

本文实例为大家分享了C++ socket实现miniFTP的方法,供大家参考,具体内容如下

客户端:

服务端:

建立连接

        连接使用 TCP 连接,服务器和客户端分别创建自己的套接字一端,服务器等待连接,客户端发起连接(并指定服务器 ip)。在两者端口号一致且不被占用的情况下,连接建立。
        在整个过程中,服务器对每一个来访的客户端建立一个连接,在客户未请求与服务器断开时,该连接一直存在,用户可以不断向服务器发出请求。(持久性、流水线型连接 )
        客户端断开后,关闭客户端的套接字部分,服务器继续等待新的连接。服务器一次只能处理一个客户端的连接,不支持并发访问。

PDU 格式

        由于 ftp 应当支持几乎任意类型文件,而几乎所有类型文件都能用二进制来解析,所以我们采用了二进制的格式来读取以及写入文件。在整个过程中,我们并不关心文件的具体内容,也无需在程序中解析文件,而是将其当作数据流看待。
        受到缓存区大小的限制,我们无法一次性传输整个文件,所以我们将文件按缓存区大小拆分成数据包分批发送,我们可以将数据及时从缓存区写入文件,这样就让出了缓存区空间。数据包仅仅包含数据,不包含头部或尾部信息。
        此外,接收文件时,recv()函数将会循环调用,因此,我们需要一个信号来通知什么时候发送完毕。
        一个想法是发送终止信号,这是可行的,但更好的方法是在一开始发送文件总字节数,让接收方根据剩余字节大小判断什么时候接收完毕。因为在写入文件时,我们需要指定写入的字节数,尤其是在发来的数据流字节数不等于缓冲区大小时。写入字节数的错误会导致文件受损。

接收确认

        我们知道 TCP 是可靠传输协议,它采取了一系列措施来保证传输不会出错。所以在使用 TCP 连接时,我们相信数据在链路层上没有出差错,它一定会成功发送到对方手上。但是在客户端接收服务器发来的文件的时候,我们仍然需要服务器发来确认信息。原因在于,虽然我们可以保证链路层不出错,但是我们无法保证应用层不出错。例如,客户端可能会给出错误的文件名,因为接收不到服务器发来的信息,所以会陷入空等状态。

ftpClient.h

#pragma  
#include<winsock.h> 
class ftpClient 
{ 
private: 
  enum { 
    SERVER_PORT = 9999, 
    BUFFER_SIZE = 4096 
  }; 
  sockaddr_in serverChannel; 
  char buffer[BUFFER_SIZE]; 
  int serverSocket; 
  int clientSocket; 
  bool isConnect; 
  char name[50]; 
 
  bool getFile(); 
  bool putFile(); 
  bool acknowledge(); 
  bool sendRequest(char* instruction); 
  bool connect2Host(const char* hostName); 
  bool getWorkDir(); 
 
public: 
  ftpClient(); 
  ~ftpClient(); 
  void start(); 
}; 

</div>

ftpClient.cpp

#define _CRT_SECURE_NO_WARNINGS 
#include"ftpClient.h" 
#include<cstdio> 
#include<io.h> 
#include<cstring> 
#include<fstream> 
 
ftpClient::ftpClient() 
{ 
  WORD wVersionRequested; 
  WSADATA wsaData; 
  int ret; 
 
  //WinSock初始化: 
  wVersionRequested = MAKEWORD(2, 2);//希望使用的WinSock DLL的版本 
  ret = WSAStartup(wVersionRequested, &wsaData); 
  if (ret != 0) 
  { 
    printf("WSAStartup() failed!\n"); 
  } 
  //确认WinSock DLL支持版本2.2: 
  if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) 
  { 
    WSACleanup(); 
    printf("Invalid Winsock version!\n"); 
  } 
  isConnect = false; 
} 
 
void ftpClient::start() 
{ 
  char c[100]; 
  char d[100]; 
  printf("这里是FTP客户端,您可以输入help查看操作方法,输入quit退出客户端\n"); 
 
  while (1) { 
    scanf("%s", c); 
    if (strcmp(c, "help") == 0) { 
      printf("get [fileName]  --  下载文件\n" 
        "put [fileName]  --  上传文件\n" 
        "ftp [ip]     --  登录FTP\n" 
        "pwd        --  显示服务器当前工作文件夹\n" 
        "cd [dirName]   --  更改当前文件夹\n" 
        "close       --  关闭与当前ftp的连接\n" 
        "quit       --  退出客户端\n" 
        ); 
    } 
    else if (strcmp(c, "get") == 0) { 
      scanf("%s", d); 
      strcat(c, " "); 
      strcat(c, d); 
      if (!isConnect) { 
        printf("you haven't connected to any server!\n"); 
      } 
      else sendRequest(c); 
    } 
    else if (strcmp(c, "put") == 0) { 
      scanf("%s", d); 
      strcat(c, " "); 
      strcat(c, d); 
      if (!isConnect) { 
        printf("you haven't connected to any server!\n"); 
      } 
      else sendRequest(c); 
    } 
    else if (strcmp(c, "ftp") == 0) { 
      scanf("%s", d); 
      if (!isConnect&&connect2Host(d)) { 
        isConnect = true; 
      } 
      else if(isConnect){ 
        printf("you have already connected to server\n" 
          "please close the connection before connect to a new server\n"); 
      } 
    } 
    else if (strcmp(c, "pwd") == 0) { 
      if (!isConnect) { 
        printf("you haven't connected to any server!\n"); 
      } 
      else sendRequest(c); 
    } 
    else if (strcmp(c, "cd") == 0) { 
      scanf("%s", d); 
      strcat(c, " "); 
      strcat(c, d); 
      if (!isConnect) { 
        printf("you haven't connected to any server!\n"); 
      } 
      else sendRequest(c); 
    } 
    else if (strcmp(c, "quit") == 0) { 
      if (isConnect) { 
        strcpy(c, "close"); 
        isConnect = false; 
        send(clientSocket, c, strlen(c) + 1, 0); 
        closesocket(clientSocket); 
      } 
      break; 
    } 
    else if (strcmp(c, "close") == 0) { 
      if (isConnect) { 
        isConnect = false; 
        send(clientSocket, c, strlen(c) + 1, 0); 
        closesocket(clientSocket); 
      } 
    } 
    else { 
      printf("syntex error\n"); 
    } 
  } 
} 
 
bool ftpClient::connect2Host(const char* hostName) 
{ 
  //创建socket 
  clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
 
  if (clientSocket < 0) { 
    printf("cannot create socket\n"); 
    return false; 
  } 
  else printf("successfully create socket\n"); 
  memset(&serverChannel, 0, sizeof(serverChannel));//初始化为0 
 
  serverChannel.sin_family = AF_INET;//channel协议家族AF_INET 
  serverChannel.sin_addr.S_un.S_addr = inet_addr(hostName);//地址 
  serverChannel.sin_port = htons(SERVER_PORT);//服务器端口 
 
                        //建立连接 
  serverSocket = connect(clientSocket, (sockaddr*)&serverChannel, sizeof(serverChannel)); 
 
  if (serverSocket < 0) { 
    printf("cannot connect to the host\n"); 
    return false; 
  } 
  else { 
    printf("successfully connect to the host\n"); 
    return true; 
  } 
} 
 
bool ftpClient::sendRequest(char* instruction) 
{ 
  int r = send(clientSocket, instruction, strlen(instruction) + 1, 0); 
  if (r == SOCKET_ERROR) { 
    printf("request failed\n"); 
    return false; 
  } 
  else { 
    printf("request success\n"); 
    char opt[5]; 
    int i = 0, j = 0; 
    while (instruction[i] != ' '&&instruction[i] != '\0') { 
      opt[i] = instruction[i]; 
      i++; 
    } 
    opt[i] = '\0'; 
    i++; 
    while (instruction[i] != '\0') { 
      name[j] = instruction[i]; 
      i++, j++; 
    } 
    name[j] = '\0'; 
    if (strcmp(opt, "get") == 0) { 
      if (getFile()) { 
        printf("successfully download\n"); 
      } 
      else printf("download failed\n"); 
    } 
    else if (strcmp(opt, "put") == 0) { 
      if (putFile()) { 
        printf("successfull



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

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

  • C++ socket实现miniFTP

相关文章

  • 2017-05-28Qt如何设置窗口屏幕居中显示以及设置大小
  • 2017-05-28C 语言程序结构示例解析
  • 2017-05-28基于C语言string函数的详解
  • 2017-05-28C语言双向链表的表示与实现实例详解
  • 2017-05-28如何通过函数指针调用函数(实现代码)
  • 2017-05-28C++多态的实现及原理详细解析
  • 2017-05-28C 语言基础教程(我的C之旅开始了)[八]
  • 2017-05-28C++基础入门教程(一):基础知识大杂烩
  • 2017-05-28C#使用反射加载多个程序集的实现方法
  • 2017-05-28Objective-C中常用的结构体NSRange,NSPoint,NSSize(CGSize),NSRect实例分析

文章分类

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

最近更新的内容

    • 详解设计模式中的Command命令模式及相关C++实现
    • 详解次小生成树以及相关的C++求解方法
    • C语言中的各种文件读写方法小结
    • C语言编程技巧 关于const和#define的区别心得
    • C++实现自顶向下的归并排序算法
    • VC++中的字体设置方法详解
    • c语言与c++基础知识点(必看)
    • C语言的递归思想实例分析
    • C++对象的动态建立与释放详解
    • c++实现十进制转换成16进制示例

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

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