2011-03-17 60 views
0

我有C++服務器與boost.asio和php客戶端寫。當我發送少量數據時,我得到了所有的數據,但是當我發送長串時,我大部分都是鬆散的。發送和接收的數據是不一樣的大小

這裏是我從我的服務器發送數據的部分,它說我已經送出了65536個字節

void handle_write(const boost::system::error_code& /*error*/, 
      size_t size/*bytes_transferred*/) { 
     cout <<size<<endl; 
    } 
    void handler_read(const boost::system::error_code&, std::size_t size) { 
     istream is(&buffer); 
     string myString; 
     getline(is, myString); 

     Manager myManager(myString); 
     string response = myManager.getResponse(); 
     boost::asio::async_write(socket_, 
       boost::asio::buffer(response), 
       boost::bind(&tcp_connection::handle_write, shared_from_this(), 
         boost::asio::placeholders::error, 
         boost::asio::placeholders::bytes_transferred)); 

    } 

在這裏,我使字符串我將派出

string getMap(string name, string pass) { 
      if (name == "admin" && pass == "123") { 
       string response = ""; 
       ConvertTypes types; 
       response = types.intToString(MAP_HEIGHT) + " "; 
       response += types.intToString(MAP_WIDTH) + "\r\n"; 
       for (int i=0; i<MAP_HEIGHT;i++) { 
        for (int j=0;j<MAP_WIDTH;j++) { 
         response += types.intToString(
           worldMap[i][j].getHeight()) + " "; 
         response += types.intToString(
           worldMap[i][j].getIsTown()) + " "; 
         response += string (1, worldMap[i][j].getTetrain()) 
           +"\r\n"; 
        } 
       } 
       return response; 
      } else { 
       return ""; 
      } 
     } 

在PHP端我讀取發送的數據,stream_get_meta_data說我只收到8183字節的數據。

print_r($this->socket->getStatus()); 

     for ($i=0; $i<$MAP_HEIGHT;$i++) { 
      for ($j=0; $j<$MAP_WIDTH;$j++) { 

       $this->response = $this->socket->readLine(); 
       $this->response = explode(' ', $this->response); 
       echo "<p>"; 
       echo "$i $j <br>"; 
       print_r($this->response); 
       echo '<br>'; 
       print_r($keyArray); 
       $map[$i][$j] = array_combine($keyArray, $this->response); 
       $this->response = $this->socket->readLine(); 
      } } 

     } 
+0

我不知道PHP,但是不能保證網絡數據包將全部在一個塊中傳遞,如果您稍等一會然後再次嘗試讀取,是否還有更多信息可用? – forsvarir 2011-03-17 15:45:03

回答

2

您可以通過套接字發送一個大的塊,但接收方可能會更小尺寸的若干塊,例如:

send -> 10000 bytes 

receive <- 3000 bytes 
receive <- 2000 bytes 
receive <- 4500 bytes 
receive <- 500 bytes 

這只是一個例子,TCP並不保證發送和接收塊將是相同的大小。

+0

+1在服務器端調用'send'不等於在客戶端對'recv'的一次調用。這是理解的重要概念。 – 2011-03-17 18:34:02

0

我找到了答案。我以不安全的方式從服務器發送數據。當async_write放棄控制其他的數據丟失。

你要通過串到這個類:

class shared_const_buffer { 
public: 
    // Construct from a std::string. 
    explicit shared_const_buffer(const std::string& data) 
    : data_(new std::vector<char>(data.begin(), data.end())), 
     buffer_(boost::asio::buffer(*data_)) 
    { 
    } 

    // Implement the ConstBufferSequence requirements. 
    typedef boost::asio::const_buffer value_type; 
    typedef const boost::asio::const_buffer* const_iterator; 
    const boost::asio::const_buffer* begin() const { return &buffer_; } 
    const boost::asio::const_buffer* end() const { return &buffer_ + 1; } 

private: 
    boost::shared_ptr<std::vector<char> > data_; 
    boost::asio::const_buffer buffer_; 
}; 

並且不發送該緩衝區原始字符串。這樣你就不會丟失數據。