FTP仿真中的套接字工作流程

时间:2013-12-15 10:44:44

标签: c++ winsock winsock2

我正在尝试通过套接字实现客户端 - 服务器通信。主要任务是:

  1. 从客户端向服务器发送命令

  2. 从服务器向客户端发送数据

  3. 从客户端向服务器发送数据

  4. 命令应该来自port1,数据来自port2。

    我在没有多线程的情况下工作但我在理解如何处理套接字时遇到了一些问题。

    当前情况:

    1.Server启动(socketbindlisten用于命令和信息套接字)并使用此函数进行无限循环:

    void FTPServer::waitForConnection()
    {
      sockaddr_in client;
      int clientsize = sizeof(client);
    
      SOCKET clientSocket = accept(_infoSocket, (struct sockaddr*)&client, &clientsize);
    
      if (clientSocket == INVALID_SOCKET)
      {
        cout << " Accept Info Error" << endl;
      }
      else
      {
        cout << " Accept Info OK" << endl;
    
        char* buff = new char[CHUNK_SIZE];
        string fullRequest;
        int rc = recv(clientSocket, buff, CHUNK_SIZE, 0);
        if (rc == SOCKET_ERROR)
        {
          cout << " Recieve Info Error" << endl;
        }
        else
        {
          buff[rc] = NULL;
          fullRequest.append(buff);
          cout << " Recieve Info OK" <<endl;
          if (executeCommand(fullRequest, clientSocket))
          {
            logOperation(client, fullRequest.c_str());
          }
        }
    
        delete buff;
      }
    }
    

    2.Client启动(socketconnect),在相同端口创建2个套接字,等待用户输入。

    3.用户类型“LIST”,客户端检查它是否是有效命令并发送它。

    bool FTPClient::sendToServer(string data, const bool verbose)
    {
      int n = 0;
    
      while (data.size() > CHUNK_SIZE)
      {
        string s = data.substr(CHUNK_SIZE).c_str();
        n += send(_infoSocket, data.substr(CHUNK_SIZE).c_str(), CHUNK_SIZE, 0);
        data = data.substr(CHUNK_SIZE+1);
      }
      n+=send(_infoSocket, data.c_str(), data.size(), 0);
      cout<<n<<endl;
      if(n<0)
      {
        cout<<"Error: sending"<<endl;
        return 0;
      }
    
      if (verbose)
      cout<<"Send "<<n<<" bytes"<<endl;
    
      return true;
    }
    

    4.Servers接收它,在_dataSocket接受并发送可用文件列表。

    5.Client收到列表:

    string FTPClient::getDataFromServer(const bool verbose)
    {
      char data[CHUNK_SIZE];
      int size = recv(_dataSocket, data, strlen(data), 0);
      if (size > 0)
      {
        int n = 0;
        string res;
        while (size > CHUNK_SIZE)
        {
          int buff = recv(_dataSocket, data, CHUNK_SIZE, 0);
          res.append(data);
          size -= buff;
          n += buff;
        }
    
        n+= recv(_dataSocket, data, CHUNK_SIZE, 0);
        res.append(data);
        if (verbose)
        cout<<"Recevied "<<n<<" bytes"<<endl;
    
        res.resize(n);
        return res;
      }
      else
      {
        return "";
      }
    }
    

    直到这个,它有效。但如果再次尝试执行相同的命令,我什么都没得到。 我认为,问题在于,对于每个connect,我们在服务器端需要accept。 在主循环服务器中只从客户端获得一个连接。关闭客户端命令套接字并在此处仅在每个请求选项上重新连接它吗?任何其他建议(“Google it”除外)均受到高度赞赏。

0 个答案:

没有答案