1

I have TCP/IP server running under embedded linux:

int sId = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);

sockaddr_in servAddr;
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servAddr.sin_port = htons(5000);
bind(sId, (sockaddr*)(&servAddr), sizeof(servAddr));

listen(sId, 10);

int cId = accept(sId, NULL, NULL);

After executing the code above I can receive messages from client with read() and send the responses with write(). For example like that:

for (;;)
{
    int c = std::cin.get();

    switch(c)
    {
    case 'q': break;
    case 'r': recv(cId, /*...*/ , MSG_DONTWAIT); // I skip the code responsible for displaying the message
    case 'w': write(cId, ... // as above
    }
}

As long as the client is connected, everything is fine. The problem start when client disconnects and I try to send a message to it. When I call write() for the first time after disconnecting it returns success, and when I call it second time the program quits without error.

Is there some smart way to detect such error?

PS. I addded simplified code to present the problem. In created program, receiving messages and sending replies is implemented in separate threads. That's why I'm looking for something that would allow me to detect error when calling write().

Avert
  • 435
  • 3
  • 17
  • 2
    Did you read the manual for `write(2)`? "On error, -1 is returned, and `errno` is set appropriately.` – Thomas Feb 08 '18 at 10:58
  • Did you read my post? I get no error whatsoever. The program just quits. – Avert Feb 08 '18 at 10:59
  • 2
    Your process is probably terminating due to a `SIGPIPE` signal. – Sam Varshavchik Feb 08 '18 at 11:24
  • Run the program with strace and post the output. strace ./yourprogram – gj13 Feb 08 '18 at 11:28
  • I don't have strace on the system, so it could be problematic :) But it appears that SIGPIPE was the problem, because when I replaced write() with send() with MSG_NOSIGNAL flag, the problem is no more. I get -1 error. Thx ;) – Avert Feb 08 '18 at 11:47
  • In the server code, are you looping for the msgs from the client ? If yes then drop the SOCK_NONBLOCK flag while creating the socket, and when client quits, in the server side the read returns with empty message with strlen zero, this is when you know client has quit, so make sure when you dont write onto that socket any more. – Prabhakar Lad Feb 08 '18 at 12:25
  • This solution doesn't always work. It could be possible that I write something to socket before receiving message that it is already closed. – Avert Feb 08 '18 at 12:44
  • @gj13: note that [this deleted answer of yours](https://stackoverflow.com/a/48462901/522444) is being discussed on meta: [Please help me undelete this community-deleted quesion](https://meta.stackoverflow.com/questions/380026/please-help-me-undelete-this-community-deleted-quesion) – Hovercraft Full Of Eels Feb 10 '19 at 22:42

0 Answers0