tcp连接后就可以异步读数据了,如:

asio::async_read(socket...

如果remote endpoint关闭,此时再发起asio::async_read会出现错误,提示"系统找不到指定的文件",实际上是socket已经无效了,错误号2,自然不能从socket上读取数据。


 

1. socket.local_endpoint()  返回的ip是 "0.0.0.0", 而不是本机IP地址,0.0.0.0 is the "any" address
   要获取本机IP请参考:

 

tcp::resolver resolver(io_service);
tcp::resolver::query query(host_name(), "");
tcp::resolver::iterator iter = resolver.resolve(query);

 

2.  io_service.run()阻塞问题

    Actually, io_service.run() blocks if it has "work" to do.
   In general, "work" means an unfinished asynchronous operation.

3.  Async Chat example questions, why post()?
Re: [asio-users] Async Chat example questions
From: Christopher Kohlhoff <chris@ko...> - 2006-08-03 07:58
Hi Andrew,

kingos@op... wrote:
> Some more questions from chat_client.cpp
>
> 1. How many threads end up running (is it 2 or 3)?

The actual answer depends on the platform you run on, but from the
application's point of view it's 2. The two threads are:

* The main thread, which is responsible for reading the input
from the user.

* The io_service.run() thread, which is used to perform all
actions associated with the chat_client object.

> ie. does async_write spawn a new thread or anything?

No.

> 2. Related to 1, why does the function write() call post
> straight away? why not just call async_write? Since it does
> call post, why then call async_write from the other thread, if
> you are just putting it in a queue to be processed by the same
> thread?

The data members of the chat_client object are (deliberately)
not thread safe. Therefore it is necessary to ensure that all
accesses to these members are synchronised in some way. This
means it is not safe to call async_write directly on the socket
from the main thread when the socket might also be accessed from
the background thread.

In this example, thread safety is achieved by ensuring that the
members are only accessed from within handlers that were
dispatched through the io_service.post() call. The io_service
provides a guarantee that any handlers passed to
io_service.post() (or io_service.dispatch()) are only invoked
from inside a call to io_service.run(). As there is only one
thread calling io_service.run() in this example, the chat_client
data members will only ever be accessed from one thread.

> 3. Why is there no check necessary for if the socket has
> connected succesfully or not? is this because the write
> function is posted to the t thread, and it will be busy
> connecting to the server? Or is this just an oversight?

Just an oversight.

> 4. If you wanted to send a connect event back to the int
> main() thread, how would you do that? can you do an
> io_service::post the other way? can you somehow obtain the
> main thread from the io_service?

In this example, it's a bit difficult to do, since the main
thread is blocked waiting for input from the user. However in
general you can indeed have an io_service object per-thread if
you want to pass events from one thread to another.

> 5. Why at the end of the main function is t.join() called.
> Could you instead call io_service.run()?

No, since that would mean we'd lose the thread safety guarantee
described in the answer to 2.

> If the answer to question 1 was that there are 3 threads
> running (ie. async_write goes to another thread), what is the
> point of spawning this thread?

The io_service::run() thread is only needed because the main
thread has to block on the input from the user. If your program
doesn't need to block on user input in that particular way, then
you don't need the extra thread and can simply call
io_service::run() from the main thread. This is what most of the
other examples do.

Cheers,
Chris


 

4. 线程安全
   
Re: [asio-users] Thread Safety: Shared objects: Unsafe.
From: Christopher Kohlhoff <chris@ko...> - 2007-01-26 22:39
Hi Boris,

On Fri, 26 Jan 2007 14:21:08 +0000 (UTC), "Boris" <monade@gm...>
said:
> Hi, What does the statement above from the docs mean for asio objects?
> Is it allowed to call two different member functions of a shared
> object from two different threads?

No.

> Or is it generally unsafe to access a shared object from different
> threads concurrently?

Yes.

Only objects marked "Shared objects: Safe" can be accessed from
different threads concurrently. An io_service object provides this level
of safety, for example.

> My use case is to run a gui in the main thread and doing asio stuff in
> a secondary thread. For syncing I use io_service::post for one
> direction and gui event handling for the other.
>
> For example:
> 1. Is it safe to call basic_datagram_socket::close() from the main
> thread while a secondary thread is running the socket?

If by running the socket you mean accessing any member functions of the
socket (async_send, async_receive or whatever) then this is not safe.

> 2. Same question for basic_deadline_timer::cancel(). Or do I have to
> wrap this call with ioService.post( boost::bind(
> &deadline_timer::cancel, &myTimer))?

Again, calling cancel() directly is not safe.

For both 1 and 2, a good solution is to do as you suggest and use
io_service::post() to ensure that all operations are performed in the
one thread.

> asio objects have lots of member functions. How do I know which ones
> are safe to use concurrently in the described sense?

For the moment, you should consider none of the member functions safe to
use concurrently.

However, in the future there will probably be a change to asio's
guarantees to specify that concurrent "read" operations are safe. This
is being discussed by the C++ committee with respect to threads support
in C++. What a "read" operation means is yet to be defined, but is
probably a const member function. In this case, the socket and timer
objects would provide the following thread-safety guarantees:

write + write: unsafe
read + write: unsafe
read + read: safe

(Asio objects may already meet this requirement, but I have not yet
audited the code to make sure.)

In any case, as both basic_datagram_socket::close() and
basic_deadline_timer::cancel() are write operations you would still have
to do something like io_service::post() to make it safe.

Cheers,
Chris