2013-04-15 79 views
0

我有以下代碼,我試圖通過手動更改套接字的端點將數據包發送到特定的客戶端,我不知道如何配置套接字以使用async_write函數發送數據包。第44-47行用於嘗試解決升壓異步服務器示例(已修改)內的問題。如何將本地端點綁定到套接字?

#include <cstdlib> 
#include <iostream> 
#include <boost/bind.hpp> 
#include <boost/asio.hpp> 

using boost::asio::ip::tcp; 

class session 
{ 
public: 
    session(boost::asio::io_service& io_service) 
    : socket_(io_service) 
    { 
    } 

    tcp::socket& socket() 
    { 
    return socket_; 
    } 

    void start() 
    { 
     std::cout<<"start(): "<<std::endl; 
      socket_.async_read_some(boost::asio::buffer(data_, max_length), 
      boost::bind(&session::handle_read, this, 
      boost::asio::placeholders::error, 
      boost::asio::placeholders::bytes_transferred)); 
    } 
void read_handler(const boost::system::error_code& ec, std::size_t bytes_transferred); 


private: 
    void handle_read(const boost::system::error_code& error, 
     size_t bytes_transferred) 
    { 
     std::cout<<"handle read: bytes_transferred"<<bytes_transferred<<std::endl; 
    if (!error) 
    { 
      data_ = {'0','1','2','3','4','5','6','7','8','9'}; 
      /*read_handler(error, bytes_transferred); 
      boost::asio::async_write(socket_,boost::asio::buffer(data_, bytes_transferred), 
       boost::bind(&session::handle_write, this, 
          boost::asio::placeholders::error));*/ 
      boost::system::error_code ec; 
      boost::asio::ip::tcp::endpoint endpoint = socket_.remote_endpoint(ec); 
      std::cout<<"ip address: "<<endpoint.address()<<std::endl; 
      std::cout<<"port: "<<endpoint.port()<<std::endl; 
      //how to get the socket to send data to specific port, ip-address e.g. changing the ip-address and port by editing it? 
      async_write(socket_, boost::asio::buffer(data_, max_length), boost::bind(&session::writeHandler, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); 
    } 
    else 
    { 
     delete this; 
    } 
    } 
    void writeHandler(const boost::system::error_code& errorCode, size_t bytesTransferred) 
    { 
     std::cout << "DEBUG> Transfered " << bytesTransferred << " bytes to " << socket_.remote_endpoint().address().to_string() << std::endl; 
    } 
    void handle_write(const boost::system::error_code& error) 
    { 
     std::cout<<"handle write: "<<std::endl; 

    if (!error) 
    { 
      std::cout<<"before: "<<data_<<std::endl; 

      socket_.async_read_some(boost::asio::buffer(data_, max_length), 
      boost::bind(&session::handle_read, this, 
      boost::asio::placeholders::error, 
      boost::asio::placeholders::bytes_transferred)); 

      std::cout<<"after: "<<data_<<std::endl; 
    } 
    else 
    { 
     delete this; 
    } 
    } 

    tcp::socket socket_; 
    enum { max_length = 1024 }; 
    char data_[max_length]; 
}; 
void session::read_handler(const boost::system::error_code& ec, std::size_t bytes_transferred) 
{ 
     std::cout<<bytes_transferred<<std::endl; 
} 

class server 
{ 
public: 
    server(boost::asio::io_service& io_service, short port) 
    : io_service_(io_service), 
     acceptor_(io_service, tcp::endpoint(tcp::v4(), port)) 
    { 
    start_accept(); 
    } 


private: 
    void start_accept() 
    { 
    session* new_session = new session(io_service_); 
    acceptor_.async_accept(new_session->socket(), 
     boost::bind(&server::handle_accept, this, new_session, 
      boost::asio::placeholders::error)); 
    } 

    void handle_accept(session* new_session, 
     const boost::system::error_code& error) 
    { 
    if (!error) 
    { 
     new_session->start(); 
    } 
    else 
    { 
     delete new_session; 
    } 

    start_accept(); 
    } 

    boost::asio::io_service& io_service_; 
    tcp::acceptor acceptor_; 
}; 

int main() 
{ 
    try 
    { 
    boost::asio::io_service io_service; 
    server s(io_service, 4000); 

    io_service.run(); 
    } 
    catch (std::exception& e) 
    { 
    std::cerr << "Exception: " << e.what() << "\n"; 
    } 

    return 0; 
} 

回答

2

它看起來像你試圖將一些UDP概念應用到TCP流。

TCP需要通過3次握手建立連接。 因此,您不能簡單地通過修改套接字的IP遠程端點地址來將數據發送到另一個客戶端。

TCP服務器偵聽傳入連接,接受它們,並在此進程結束時有一個有效的TCP套接字,您可以在其中寫入數據。每個客戶端都有自己的套接字。另請注意,TCP套接字提供了一個數據流(不是數據包/數據報)。

另一方面,UDP沒有連接的概念。您可以使用相同的UDP套接字(boost :: asio :: ip :: udp :: socket :: send_to)將數據報發送到多個端點。

+0

如果在客戶端和服務器之間建立了TCP連接,在服務器端有一些列表跟蹤連接到它的客戶端,不能以某種方式訪問​​特定的客戶端? – pandoragami

+2

您用作模板的示例代碼不會跟蹤客戶端(在本例中爲「會話」實例)。如果您需要連接到服務器的客戶端列表,您通常會在接受服務器類中的連接時構建它。 – jcm

+0

但是,當我們連接客戶端時,我會存儲什麼對象? – pandoragami

相關問題