2016-02-19 58 views
1

我將包含所有相關的代碼部分,但我確定問題出在我的網絡上,而不是我的代碼,因爲如果我在一臺計算機上回送代碼,我的代碼工作得很好。不過,如果您在代碼中看到任何明顯的錯誤,我想知道。ASIO客戶端服務器在同一臺PC上連接良好,但在本地網絡上失敗

參考basic_server代碼(僅相關部分):

connection_id basic_server::start_listening(const std::string & ip_address, const std::string & port) { 
    asio::ip::tcp::resolver resolver(*service); 
    asio::ip::tcp::resolver::query query(ip_address, port); 
    asio::ip::tcp::endpoint endpoint = *(resolver.resolve(query)); 

    connection_id id(get_seed()); 
    while (connections.contains(id)) { 
     std::this_thread::yield(); 
     id = get_seed(); 
    } 
    connections[id] = connection_ptr(new connection(id, *service, ip_address, port)); 
    connection_ptr conn = connections[id]; 
    conn->state = listening; 

    if (!acceptor->is_open()) { 
     acceptor->open(endpoint.protocol()); 
    } 
    if (current_ip != ip_address || current_port != port) { 
     acceptor->bind(endpoint); 
     current_ip = ip_address; 
     current_port = port; 
    } 
    acceptor->listen(asio::socket_base::max_connections); 

    acceptor->async_accept(
     conn->get_socket(), 
     std::bind(
      &basic_server::connect, 
      this, 
      std::placeholders::_1, 
      id 
     ) 
    ); 
    return id; 
} 

connection_id basic_server::start_connecting(const std::string & ip_address, const std::string & port) { 
    asio::ip::tcp::resolver resolver(*service); 
    asio::ip::tcp::resolver::query query(ip_address, port); 
    asio::ip::tcp::endpoint endpoint = *(resolver.resolve(query)); 

    connection_id id(get_seed()); 
    while (connections.contains(id)) { 
     std::this_thread::yield(); 
     id = get_seed(); 
    } 
    connections[id] = connection_ptr(new connection(id, *service, ip_address, port)); 
    connection_ptr conn = connections[id]; 
    conn->state = connecting; 

    conn->get_socket().async_connect(
     endpoint, 
     std::bind(
      &basic_server::connect, 
      this, 
      std::placeholders::_1, 
      id 
     ) 
    ); 
    return id; 
} 

參考服務器代碼:

#include "../../Utilities/BasicServer/Basic Server.h" 

int main() { 
    server::basic_server this_server; 
    server::connection_id id = this_server.start_listening("::1", "6118"); 
    const std::set<server::connection_state> valid_states = { server::open, server::listening, server::connecting }; 
    while (this_server.connection_status(id) == server::listening) std::cout << "Waiting for Client.\r"; 
    std::cout << std::endl; 
    while (true) { 
     if (valid_states.find(this_server.connection_status(id)) == valid_states.end()) { 
      std::cout << "We've lost connection with the client." << std::endl; 
      break; 
     } 
     server::data_pair data; 
     bool successful_read = this_server.read_from_queue(data); 
     if (!successful_read) { 
      std::this_thread::yield(); 
      continue; 
     } 
     server::connection_id read_id = data.first; 
     server::data_vector & read_vector = data.second; 
     std::string line; 
     line.resize(70); 
     std::copy(read_vector.begin(), read_vector.begin() + std::min(70ull, read_vector.size()), line.begin()); 
     std::cout << line << std::endl; 
    } 
    system("pause"); 
    return 0; 
} 

參考客戶端代碼(從服務器的代碼沒有太大的區別):

#include "../../Utilities/BasicServer/Basic Server.h" 

int main(int argc, char ** argv) { 
    server::basic_server this_client; 
    std::string ip_address; 
    if (argc < 2) return 0; 
    ip_address = argv[1]; 
    server::connection_id id = this_client.start_connecting(ip_address, "6118"); 
    const std::set<server::connection_state> valid_states = { server::open, server::listening, server::connecting }; 
    while (this_client.connection_status(id) == server::connecting) std::cout << "Connecting to Server with IP address \"" << ip_address << "\"\r"; 
    std::cout << std::endl; 
    if (this_client.connection_status(id) == server::open) { 
     std::cout << "We're connected!" << std::endl; 
    } 
    else { 
     std::cout << "Unable to connect." << std::endl; 
     system("pause"); 
     return 0; 
    } 
    while (true) { 
     if (valid_states.find(this_client.connection_status(id)) == valid_states.end()) { 
      std::cout << "We've lost connection." << std::endl; 
      break; 
     } 
     std::string line; 
     std::getline(std::cin, line); 
     std::cout << "Attemping to write \"" << line << "\"" << std::endl; 
     this_client.write_to_connection(id, &line.front(), line.size() * sizeof(unsigned char)); 
     if (line == "") break; 
    } 
    system("pause"); 
    return 0; 
} 

所以我的問題的基本要點是,當我嘗試從一個comp子宮到另一個(通過我的本地網絡)連接失敗。如果我在同一臺計算機上運行服務器和客戶端,它可以正常工作。我試過以下所有內容:

  • ping接收/發送計算機以驗證他們互相看到:他們確實。
  • 運行tracert來檢查連接:它們在一跳中到達彼此,不涉及外部連接。
  • 在使用IPv6和IPv4(我的路由器支持兩者)之間進行交換以嘗試連接:我確定在回送時,如果客戶端使用IPv4環回地址,則使用IPv6作爲服務器綁定端點將不起作用,反之亦然,但如果它們都使用IPv6或IPv4,則它在環回上運行良好。這些都不能跨越不同的電腦。

有什麼想法是怎麼回事?

+0

你的服務器監聽本地主機只:當你聽0.0.0.0 IP或者使用端點,而不指定監聽IP地址創建監聽任何IP可用'start_listening(「:: 1」,「6118」 );'。這是錯誤嗎? – PSIAlt

+0

@psialt我如何指定我想要聽取來自任何地方的連接,而不僅僅是本地? – Xirema

+0

在這種情況下,你應該監聽'0.0.0.0'或者如果你創建了一個端點'ip :: tcp :: endpoint(ip :: tcp :: v4(),6118)' – PSIAlt

回答

1

正如我們在評論中發現的那樣,問題在於網絡防火牆和只監聽本地主機。 ip::tcp::endpoint(ip::tcp::v4(), 6118)

相關問題