Boost logo

Boost Users :

Subject: Re: [Boost-users] asio tcp async_read never returns
From: l.jay Yuan (pass86_at_[hidden])
Date: 2010-03-10 01:45:12


i don't see where you are send data?
both server and client are receiveing.

2010/3/10 Tom Kent <lists_at_[hidden]>:
> I am trying to convert some existing code to use boost's asio tcp
> sockets instead of our current implementation. I am able to get a very
> similar example (of a chat client/server) from the boost site working,
> but when I attempt to put the code into my own program it stops working.
>
> What I am doing:
>
>   1. Start a server process
>   2. The server process makes an empty socket and uses it to listen
> (with a tcp::acceptor) for TCP connections on a port (10010 for example)
>   3. Start a client process
>   4. Have the client process create a socket connect to the server's port
>   5. When the server sees a client is connecting, it starts listening
> for data(with async_read) on the socket and creates another empty socket
> to listen for another TCP connection on the port
>   6. When the client sees that the server has connected, it sends 100
> bytes of data (with async_write) and waits for the socket to tell it the
> send is finished...when that happens it prints a message and shuts down
>   7. When the server gets notified that its has data that has been
> read, it prints a message and shuts down
>
> Obviously, I have greatly trimmed this code down from what I'm trying to
> implement, this is as small as I could make something that reproduces
> the problem. I'm running on windows and have a visual studio solution
> file you can get (http://boost.teeks99.com/BoostConnectionTest.zip).
> There's some memory leaks, thread safety problems, and such, but that's
> because I'm taking stuff out of existing code, so don't worry about them.
>
> Anyway, here's the files one header with some common stuff, a server,
> and a client.
>
> Connection.hpp:
> #ifndef CONNECTION_HPP
> #define CONNECTION_HPP
> #include <boost/system/error_code.hpp>
> #include <boost/asio.hpp>
> #include <boost/bind.hpp>
>
> class ConnectionTransfer
> {
> public:
>   ConnectionTransfer(char* buffer, unsigned int size) :
>      buffer_(buffer), size_(size)   {
>   }
>   virtual ~ConnectionTransfer(void){}
>
>   char* GetBuffer(){return buffer_;}
>   unsigned int GetSize(){return size_;}
>
>   virtual void CallbackForFinished() = 0;
>
> protected:
>   char* buffer_;
>   unsigned int size_;
> };
>
> class ConnectionTransferInProgress
> {
> public:
>   ConnectionTransferInProgress(ConnectionTransfer* ct):
>      ct_(ct)
>   {}
>   ~ConnectionTransferInProgress(void){}
>
>   void operator()(const boost::system::error_code& error){Other(error);}
>   void Other(const boost::system::error_code& error){
>      if(!error)
>         ct_->CallbackForFinished();
>   }
> private:
>   ConnectionTransfer* ct_;
> };
>
> class Connection
> {
> public:
>   Connection(boost::asio::io_service& io_service):
>   sock_(io_service)
>   {}
>   ~Connection(void){}
>   void AsyncSend(ConnectionTransfer* ct){
>      ConnectionTransferInProgress tip(ct);
>      //sock_->async_send(boost::asio::buffer(ct->GetBuffer(),
>      //   static_cast<std::size_t>(ct->GetSize())), tip);
>      boost::asio::async_write(sock_, boost::asio::buffer(ct->GetBuffer(),
>         static_cast<std::size_t>(ct->GetSize())), boost::bind(
>         &ConnectionTransferInProgress::Other, tip,
> boost::asio::placeholders::error));
>   }
>   void AsyncReceive(ConnectionTransfer* ct){
>      ConnectionTransferInProgress tip(ct);
>      //sock_->async_receive(boost::asio::buffer(ct->GetBuffer(),
>      //   static_cast<std::size_t>(ct->GetSize())), tip);
>      boost::asio::async_read(sock_, boost::asio::buffer(ct->GetBuffer(),
>         static_cast<std::size_t>(ct->GetSize())), boost::bind(
>         &ConnectionTransferInProgress::Other, tip,
> boost::asio::placeholders::error));
>   }
>
>   boost::asio::ip::tcp::socket& GetSocket(){return sock_;}
> private:
>   boost::asio::ip::tcp::socket sock_;
> };
> #endif //CONNECTION_HPP
>
> BoostConnectionClient.cpp:
> #include "Connection.hpp"
>
> #include <boost/asio.hpp>
> #include <boost/bind.hpp>
> #include <boost/thread.hpp>
> #include <iostream>
>
> using namespace boost::asio::ip;
>
> bool connected;
> bool gotTransfer;
>
> class FakeTransfer : public ConnectionTransfer
> {
> public:
>   FakeTransfer(char* buffer, unsigned int size) :
> ConnectionTransfer(buffer, size)
>   {
>   }
>   void CallbackForFinished()
>   {
>      gotTransfer = true;
>   }
> };
>
> void ConnectHandler(const boost::system::error_code& error)
> {
>   if(!error)
>      connected = true;
> }
>
> int main(int argc, char* argv[])
> {
>   connected = false;
>   gotTransfer = false;
>
>   boost::asio::io_service io_service;
>
>   Connection* conn = new Connection(io_service);
>
>   tcp::endpoint ep(address::from_string("127.0.0.1"), 10011);
>   conn->GetSocket().async_connect(ep, ConnectHandler);
>
>   boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service));
>
>   while(!connected)
>   {
>      boost::this_thread::sleep(boost::posix_time::millisec(1));
>   }
>   std::cout << "Connected\n";
>
>   char data[100];
>   FakeTransfer* ft = new FakeTransfer(data, 100);
>   conn->AsyncReceive(ft);
>
>   while(!gotTransfer)
>   {
>      boost::this_thread::sleep(boost::posix_time::millisec(1));
>   }
>
>   std::cout << "Done\n";
>
>   return 0;
> }
>
> BoostConnectionServer.cpp:
> #include "Connection.hpp"
>
> #include <boost/asio.hpp>
> #include <boost/bind.hpp>
> #include <boost/thread.hpp>
> #include <iostream>
>
> using namespace boost::asio::ip;
>
> Connection* conn1;
> bool conn1Done;
> bool gotTransfer;
> Connection* conn2;
>
> class FakeAcceptor
> {
> public:
>   FakeAcceptor(boost::asio::io_service& io_service, const
> tcp::endpoint& endpoint)
>      :
>      io_service_(io_service),
>      acceptor_(io_service, endpoint)
>  {
>      conn1 = new Connection(io_service_);
>      acceptor_.async_accept(conn1->GetSocket(),
>         boost::bind(&FakeAcceptor::HandleAccept, this, conn1,
>         boost::asio::placeholders::error));
>   }
>   void HandleAccept(Connection* conn, const boost::system::error_code&
> error)
>   {
>      if(conn == conn1)
>         conn1Done = true;
>      conn2 = new Connection(io_service_);
>      acceptor_.async_accept(conn2->GetSocket(),
>         boost::bind(&FakeAcceptor::HandleAccept, this, conn2,
>         boost::asio::placeholders::error));
>   }
>   boost::asio::io_service& io_service_;
>   tcp::acceptor acceptor_;
> };
>
> class FakeTransfer : public ConnectionTransfer
> {
> public:
>   FakeTransfer(char* buffer, unsigned int size) :
> ConnectionTransfer(buffer, size)
>   {
>   }
>   void CallbackForFinished()
>   {
>      gotTransfer = true;
>   }
> };
>
> int main(int argc, char* argv[])
> {
>   boost::asio::io_service io_service;
>   conn1Done = false;
>   gotTransfer = false;
>   tcp::endpoint endpoint(tcp::v4(), 10011);
>   FakeAcceptor fa(io_service, endpoint);
>   boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service));
>
>   while(!conn1Done)
>   {
>      boost::this_thread::sleep(boost::posix_time::millisec(1));
>   }
>   std::cout << "Accepted incoming connection\n";
>
>   char data[100];
>   FakeTransfer* ft = new FakeTransfer(data, 100);
>   conn1->AsyncReceive(ft);
>
>   while(!gotTransfer)
>   {
>      boost::this_thread::sleep(boost::posix_time::millisec(1));
>   }
>   std::cout << "Success!\n";
>   return 0;
> }
>
> I've searched around a bit, but haven't had much luck.  As far as I can
> tell, I'm almost exactly matching the sample, so it must be something
> small that I'm overlooking.  Any help is much appreciated!
>
> Tom
>
> P.S.
> cross posted to stack overflow: http://stackoverflow.com/questions/2412520/
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net