About full-duplex sockets

Sockets are supposed to be full-duplex, right? So the endpoints should be able to send and receive literally at the same time. But how do you handle that at the application level? For example, you might have the client making normal synchronous requests and the server sending asynchronous events at any time.

I'm thinking something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void receive_thread(){
    while (auto message = socket.receive()){
        Future<Message> &future = socket.find_future(message.port());
        future.fulfill(message);
    }
}

void request_thread(){
    auto port = socket.allocate_port();
    while (auto request = get_user_request()){
        Message message(request, port);
        Future<Message> future = socket.send(message);
        auto response_message = future.wait();
        //Handle response.
    }
}

void random_notification_thread(){
    auto port = socket.allocate_port();
    while (auto request = get_system_event()){
        Message message(request, port);
        socket.send_without_future(message);
    }
}

I guess this works, but it seems kind of odd to me. Is this what the typical implementation for an asynchronous socket looks like?
I'm not even sure what API you are using here 🤔

But, if we are talking about the traditional POSIX Sockets API (or, similarly, the Winsock API), then yes, sockets usually are "full duplex" (bidirectional), in the sense that both sides can send/receive at any time. The thing is that any "incoming" data goes into a buffer and remains there, waiting to be processed, until you actually "read" it from the socket. So you don't need to be reading all the time; only when you actually expect that there is something to be read. You won't "miss" anything, it'll be sitting in the buffer. Quite often you also won't use "blocking" reads (which may block for an indefinite amount of time, until, eventually, something to be read comes in), but instead use some sort of "event" mechanism, which will notify you as soon as some "incoming" data is ready to be read/processed. In the meantime you can do something else, such as sending data or doing actual computations. Or just sleeping, if currently there is nothing to do.

Furthermore, even though a socket is "full duplex", there almost always is some sort of protocol that dictates who needs to send or receive at which time, and what needs to be sent/received. Most often, the "client" connects to the "server" and then sends (writes) some sort of request. Once it has sent the request, it stops sending (writing) and it simply waits until it can receive (read) the response. Meanwhile, the server doesn't do anything until it has actually received (read) a request from the client. It then parses the request, does whatever the request requires and finally sends (writes) back a response to the client. Then we can go on with the next request/response pair.

Of course, we can also do some sort of "pipelining" where the clients can send multiple requests right away, i.e. the client does not have to wait for the response for request n before it can send request n+1. This allows multiple requests to be "on-the-fly" at the same time, and the server may then process these requests in any order it deems suitable, or even process multiple requests concurrently (e.g. by dispatching the requests to multiple threads). But that all totally depends on the concrete application and how the protocol is defined.

IMO, first and foremost, you have to think about the protocol and what you want to achieve. Then you can think about how to implement it.
Last edited on
Topic archived. No new replies allowed.