Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
321 views
in Technique[技术] by (71.8m points)

c++ - Proper way to close a blocking UDP socket

I have a C++ object that creates a thread to read from a blocking UDP socket:

mRunning.store(true);
while (mRunning.load(boost::memory_order_consume)) {
    ...
    int size = recvfrom(mSocket, buf, kTextBufSize , 0,
                        (struct sockaddr *) &packet->mReplyAddr.mSockAddr, (socklen_t*)&packet->mReplyAddr.mSockAddrLen);

    if (size > 0) {
        //do stuff
    }
}
return 0;

(mRunning is a boost::atomic) The object's destructor is called from another thread and does this:

mRunning.store(false);  
#ifdef WIN32
    if (mSocket != -1) closesocket(mSocket);
#else
    if (mSocket != -1) close(mSocket);
#endif
pthread_join(mThread, NULL);

This seems to work, but one of my colleagues suggested that there might be a problem if recv is interrupted in the middle of reading something. Is this thread safe? What's the correct way of closing a blocking UDP socket? (Needs to be cross-platform OSX/Linux/Windows)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There could be a lot of different problems. Moving my application from one FreeBSD version to another I found that such close() worked normally on older kernel and just hung close() until something returned from recv() on newer. And OSX is FreeBSD based :)

Portable way of closing sockets from different thread is to create pipe and block not in recv(), but in select(). When you need to close socket, write something to pipe, select() will unblock and you can safely do close().


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...