Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. SIGPIPE error when flushing a recently closed QTcpSocket
Forum Updated to NodeBB v4.3 + New Features

SIGPIPE error when flushing a recently closed QTcpSocket

Scheduled Pinned Locked Moved General and Desktop
4 Posts 4 Posters 2.9k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    RogueWarrior
    wrote on last edited by
    #1

    I'm trying to write fault-tolerant socket code that will gracefully handle a TCP connection that was closed during a conversation.

    @ for (short i=0;i<10;i++)
    if (swSocket->state() == QAbstractSocket::ConnectedState) {
    qDebug() << "Sending a message...";
    swSocket->write("Hello from Socket Writer.\r\n");
    if (swSocket->state() == QAbstractSocket::ConnectedState) {
    swSocket->flush(); // <----- Line in question
    swSocket->waitForBytesWritten(50);
    } else {
    qDebug() << "Not connected.";
    }
    sleep(1);
    } else {
    qDebug() << "Not connected.";
    }
    @

    In the above code, if I have the flush call and the receiving computer closes the connection, I get a SIGPIPE signal which crashes the program. I have tried adding signal(SIGPIPE, SIG_IGN); in my main() but that doesn't fix it. Removing the flush line fixed the problem but what I'm trying to avoid is the TCP stack queuing up my outgoing messages.

    Would I be able to accomplish this by using TCP_NODELAY? And is there a way to get flush to gracefully return?

    1 Reply Last reply
    0
    • C Offline
      C Offline
      compor
      wrote on last edited by
      #2

      afaik,

      there are 2 buffers

      application level buffer, currently maintained by your TCP socket object

      network socket buffer, maintained and handled by the OS

      the QAbstractSocket::flush() method just forces the transfer of data from 1] to 2]. There is no way to have an unbuffered QTcpSocket (QIODevice::Unbuffered option).
      However, you can accomplish TCP_NODELAY by using the QAbstractSocket::LowDelayOption option.

      Also, the way the program is structured, there is no guarantee that e.g. the state of the socket will be the same from the time line 5 was executed to when line 6 gets to be executed. Usually such programs rely heavily on the available signals of the Socket classes.

      would you mind connecting the error() and/or disconnected() signals to a simple debugging routine that will print the relevant info?

      lastly, i'm not sure why your signal handler didn't work, but if event if it did, it would mean that you should get an error on your next socket I/O operation.

      purposes as understood by the purposer will be misunderstood by others

      A 1 Reply Last reply
      0
      • C compor

        afaik,

        there are 2 buffers

        application level buffer, currently maintained by your TCP socket object

        network socket buffer, maintained and handled by the OS

        the QAbstractSocket::flush() method just forces the transfer of data from 1] to 2]. There is no way to have an unbuffered QTcpSocket (QIODevice::Unbuffered option).
        However, you can accomplish TCP_NODELAY by using the QAbstractSocket::LowDelayOption option.

        Also, the way the program is structured, there is no guarantee that e.g. the state of the socket will be the same from the time line 5 was executed to when line 6 gets to be executed. Usually such programs rely heavily on the available signals of the Socket classes.

        would you mind connecting the error() and/or disconnected() signals to a simple debugging routine that will print the relevant info?

        lastly, i'm not sure why your signal handler didn't work, but if event if it did, it would mean that you should get an error on your next socket I/O operation.

        A Offline
        A Offline
        artem_pisarenko
        wrote on last edited by
        #3

        @compor , the code in question is absolutely legal and fault-tolerant. It doesn't contain any race conditions, i.e. it's normal situation when underlying(!) system socket changes its state between line 5 and 6. There are no way to catch it even if you handle error()/disconnected() signals. Also the problem isn't TCP-specific. I personally encountered same issue with QLocalSocket. Qt implementation should handle it properly but it doesn't. Seems like it's a Qt bug (or platform-specific feature?).

        F 1 Reply Last reply
        0
        • A artem_pisarenko

          @compor , the code in question is absolutely legal and fault-tolerant. It doesn't contain any race conditions, i.e. it's normal situation when underlying(!) system socket changes its state between line 5 and 6. There are no way to catch it even if you handle error()/disconnected() signals. Also the problem isn't TCP-specific. I personally encountered same issue with QLocalSocket. Qt implementation should handle it properly but it doesn't. Seems like it's a Qt bug (or platform-specific feature?).

          F Offline
          F Offline
          fremboli
          wrote on last edited by
          #4

          @artem_pisarenko
          Would have been nice if you had posted the solution here :)
          https://stackoverflow.com/a/55757737
          The Debugger.
          https://ahlamnote.blogspot.com/2006/12/gdb-ignore-sigpipe.html
          https://doc.qt.io/qtcreator/creator-debugger-engines.html#specifying-debugger-settings

          Tools > Options > Debugger > GDB
          handle SIGPIPE nostop noprint pass

          1 Reply Last reply
          1

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved