Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. recv no blocking

recv no blocking

Scheduled Pinned Locked Moved C / C++ / MFC
sysadmindata-structureshelpquestion
13 Posts 4 Posters 0 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.
  • M Offline
    M Offline
    mosine
    wrote on last edited by
    #1

    Hi, I'm developing a server multithread (multiclient) and I have a problem with recv function (c language - SO: windows). My clients send info to server every 5 seconds and recv function blocks thread until info arrives. I try with ioctlsocket, but the number of byte read always is 0; I try with flag MSG_PEEK, but the data is copied into the buffer, but is not removed from the input queue and so I have many messages. Is there a way to perform recv function no blocking? THANKS

    CPalliniC 1 Reply Last reply
    0
    • M mosine

      Hi, I'm developing a server multithread (multiclient) and I have a problem with recv function (c language - SO: windows). My clients send info to server every 5 seconds and recv function blocks thread until info arrives. I try with ioctlsocket, but the number of byte read always is 0; I try with flag MSG_PEEK, but the data is copied into the buffer, but is not removed from the input queue and so I have many messages. Is there a way to perform recv function no blocking? THANKS

      CPalliniC Offline
      CPalliniC Offline
      CPallini
      wrote on last edited by
      #2

      Usually a blocking recv is not a problem at all in a multithreaded application: the receiving thread blocks but the other threads keep runnning and the application is responsive. On the other hand, as you may find in the documentation[^], you might use non blocking mode on sockets, however, I guess, your application would be more involved.

      In testa che avete, signor di Ceprano?

      M 1 Reply Last reply
      0
      • CPalliniC CPallini

        Usually a blocking recv is not a problem at all in a multithreaded application: the receiving thread blocks but the other threads keep runnning and the application is responsive. On the other hand, as you may find in the documentation[^], you might use non blocking mode on sockets, however, I guess, your application would be more involved.

        M Offline
        M Offline
        mosine
        wrote on last edited by
        #3

        Thanks for reply. The problem is, if my server must send data to client, it waits 5 seconds because recv function blocks thread. I try to launch another thread (for each client) for send operation, but cpu works 100%.

        CPalliniC 1 Reply Last reply
        0
        • M mosine

          Thanks for reply. The problem is, if my server must send data to client, it waits 5 seconds because recv function blocks thread. I try to launch another thread (for each client) for send operation, but cpu works 100%.

          CPalliniC Offline
          CPalliniC Offline
          CPallini
          wrote on last edited by
          #4

          Quote:

          The problem is, if my server must send data to client, it waits 5 seconds because recv function blocks thread.

          As far as I know, the server's send is not blocked by the client recv.

          Quote:

          I try to launch another thread (for each client) for send operation, but cpu works 100%.

          Waiting on I/O operations should not consume CPU, there's probably a flawn in your code.

          In testa che avete, signor di Ceprano?

          M A 2 Replies Last reply
          0
          • CPalliniC CPallini

            Quote:

            The problem is, if my server must send data to client, it waits 5 seconds because recv function blocks thread.

            As far as I know, the server's send is not blocked by the client recv.

            Quote:

            I try to launch another thread (for each client) for send operation, but cpu works 100%.

            Waiting on I/O operations should not consume CPU, there's probably a flawn in your code.

            M Offline
            M Offline
            mosine
            wrote on last edited by
            #5

            I post my code:

            DWORD WINAPI cliTh1( LPVOID lpData ){
            struct CLIENT_INFO *pClientInfo;
            char szClientMsg[250];
            char packet[50];
            HANDLE clientTxThread;

            pClientInfo = (struct CLIENT\_INFO \*)lpData ;
            char \*ip = inet\_ntoa(pClientInfo->clientAddr.sin\_addr);
            printf("SOCKET:%d  - IP:%s  - THREAD\_ID:%ld\\n", pClientInfo->hClientSocket, ip   
                                                           ,GetCurrentThreadId());
            Q->pClient = pClientInfo;
            pClientInfo->primaConn = 0;
            pClientInfo->indirizzo = 0;
            pClientInfo->p = getDisconnect;
            while ( 1 ){
                if(j>=MAXELEMENTS){j=0;};
                if(WSAGetLastError()){
                    if(pClientInfo->primaConn == 1){
                        disconnectBuffer\[pClientInfo->indirizzo\] = 1;
                        pClientInfo->primaConn=0;
                    }
                    if(disconnectBuffer\[pClientInfo->indirizzo\] == 1){
                        creaPackDisc(packet, pClientInfo->indirizzo);
                        strcpy(bufferRx\[j\].packet, packet);
                        Enqueue(Q,  packet);
                        j++;
                    }else{
                        closesocket(pClientInfo->hClientSocket);
                        ExitThread(pClientInfo->txThId);
                        ExitThread(GetCurrentThreadId());
                    }
                    Sleep(1000);
                }else{
                    if((pClientInfo->primaConn == 0) && (pClientInfo->indirizzo != 0)){
                        pClientInfo->connessione = setConnect(GetCurrentThreadId(), pClientInfo->indirizzo, ip);
                        if(pClientInfo->connessione == 1){
                            pClientInfo->primaConn = 1;
                        }
                        //THREAD TX for each client
                        clientTxThread = CreateThread(NULL,0,(LPTHREAD\_START\_ROUTINE)txThread, 
                                                      pClientInfo,0,&pClientInfo->txThId);
                        if ( clientTxThread == NULL ){
                            printf("Unable to create client thread");
                        } else {
                            CloseHandle( clientTxThread ) ;
                        }
                    }
                    if(recv( pClientInfo -> hClientSocket, szClientMsg, sizeof( szClientMsg ), 0  ) > 0){
                        strcpy(bufferRx\[j\].packet, szClientMsg);
                        memset(&szClientMsg\[0\], 0, sizeof(szClientMsg));
                        pClientInfo->indirizzo = calcolaHighLow(bufferRx\[j\].packet\[1\], bufferRx\[j\].packet\[2\],  
                                                               bufferRx\[j\].packet\[3\], bufferRx\[j\].packet\[4\]);
                        Enqueue(Q,  bufferRx\[j\].packet);
            
            CPalliniC 1 Reply Last reply
            0
            • M mosine

              I post my code:

              DWORD WINAPI cliTh1( LPVOID lpData ){
              struct CLIENT_INFO *pClientInfo;
              char szClientMsg[250];
              char packet[50];
              HANDLE clientTxThread;

              pClientInfo = (struct CLIENT\_INFO \*)lpData ;
              char \*ip = inet\_ntoa(pClientInfo->clientAddr.sin\_addr);
              printf("SOCKET:%d  - IP:%s  - THREAD\_ID:%ld\\n", pClientInfo->hClientSocket, ip   
                                                             ,GetCurrentThreadId());
              Q->pClient = pClientInfo;
              pClientInfo->primaConn = 0;
              pClientInfo->indirizzo = 0;
              pClientInfo->p = getDisconnect;
              while ( 1 ){
                  if(j>=MAXELEMENTS){j=0;};
                  if(WSAGetLastError()){
                      if(pClientInfo->primaConn == 1){
                          disconnectBuffer\[pClientInfo->indirizzo\] = 1;
                          pClientInfo->primaConn=0;
                      }
                      if(disconnectBuffer\[pClientInfo->indirizzo\] == 1){
                          creaPackDisc(packet, pClientInfo->indirizzo);
                          strcpy(bufferRx\[j\].packet, packet);
                          Enqueue(Q,  packet);
                          j++;
                      }else{
                          closesocket(pClientInfo->hClientSocket);
                          ExitThread(pClientInfo->txThId);
                          ExitThread(GetCurrentThreadId());
                      }
                      Sleep(1000);
                  }else{
                      if((pClientInfo->primaConn == 0) && (pClientInfo->indirizzo != 0)){
                          pClientInfo->connessione = setConnect(GetCurrentThreadId(), pClientInfo->indirizzo, ip);
                          if(pClientInfo->connessione == 1){
                              pClientInfo->primaConn = 1;
                          }
                          //THREAD TX for each client
                          clientTxThread = CreateThread(NULL,0,(LPTHREAD\_START\_ROUTINE)txThread, 
                                                        pClientInfo,0,&pClientInfo->txThId);
                          if ( clientTxThread == NULL ){
                              printf("Unable to create client thread");
                          } else {
                              CloseHandle( clientTxThread ) ;
                          }
                      }
                      if(recv( pClientInfo -> hClientSocket, szClientMsg, sizeof( szClientMsg ), 0  ) > 0){
                          strcpy(bufferRx\[j\].packet, szClientMsg);
                          memset(&szClientMsg\[0\], 0, sizeof(szClientMsg));
                          pClientInfo->indirizzo = calcolaHighLow(bufferRx\[j\].packet\[1\], bufferRx\[j\].packet\[2\],  
                                                                 bufferRx\[j\].packet\[3\], bufferRx\[j\].packet\[4\]);
                          Enqueue(Q,  bufferRx\[j\].packet);
              
              CPalliniC Offline
              CPalliniC Offline
              CPallini
              wrote on last edited by
              #6

              Are you testing with both client and server running on the same machine? Have a look at this thread: "send and recv are cpu intensive?"[^].

              In testa che avete, signor di Ceprano?

              M 1 Reply Last reply
              0
              • CPalliniC CPallini

                Are you testing with both client and server running on the same machine? Have a look at this thread: "send and recv are cpu intensive?"[^].

                M Offline
                M Offline
                mosine
                wrote on last edited by
                #7

                Yes, I'm testing clients with server on the same machine. My goal is: if the system works fine on my pc, I will have no problems on server machine. Is there a minimal example of recv no blocking?

                CPalliniC D 2 Replies Last reply
                0
                • M mosine

                  Yes, I'm testing clients with server on the same machine. My goal is: if the system works fine on my pc, I will have no problems on server machine. Is there a minimal example of recv no blocking?

                  CPalliniC Offline
                  CPalliniC Offline
                  CPallini
                  wrote on last edited by
                  #8

                  Did you read the linked page? It is normal a 100% CPU usage if they both run on the same machine.

                  In testa che avete, signor di Ceprano?

                  1 Reply Last reply
                  0
                  • M mosine

                    Yes, I'm testing clients with server on the same machine. My goal is: if the system works fine on my pc, I will have no problems on server machine. Is there a minimal example of recv no blocking?

                    D Offline
                    D Offline
                    Daniel Pfeffer
                    wrote on last edited by
                    #9

                    If you only have one physical machine, I suggest installing Windows in a virtual machine, and running one of the tasks there. That would ensure that the platforms are separate, and would help you to track down the 100% CPU issue. IMO, a multithreaded blocking recv() implementation is conceptually much simpler than a non-blocking recv() implementation.

                    If you have an important point to make, don't try to be subtle or clever. Use a pile driver. Hit the point once. Then come back and hit it again. Then hit it a third time - a tremendous whack. --Winston Churchill

                    A 1 Reply Last reply
                    0
                    • D Daniel Pfeffer

                      If you only have one physical machine, I suggest installing Windows in a virtual machine, and running one of the tasks there. That would ensure that the platforms are separate, and would help you to track down the 100% CPU issue. IMO, a multithreaded blocking recv() implementation is conceptually much simpler than a non-blocking recv() implementation.

                      If you have an important point to make, don't try to be subtle or clever. Use a pile driver. Hit the point once. Then come back and hit it again. Then hit it a third time - a tremendous whack. --Winston Churchill

                      A Offline
                      A Offline
                      Albert Holguin
                      wrote on last edited by
                      #10

                      Daniel Pfeffer wrote:

                      IMO, a multithreaded blocking recv() implementation is conceptually much simpler than a non-blocking recv() implementation.

                      Yep, and it works really well... just be careful for hanging sockets in Linux.

                      Daniel Pfeffer wrote:

                      If you only have one physical machine, I suggest installing Windows in a virtual machine, and running one of the tasks there. That would ensure that the platforms are separate, and would help you to track down the 100% CPU issue.

                      This might actually yield the same result. The issue is the super low latency in the network when everything is co-located. Essentially if you're tx and rx run as fast as possible, it could take up all the CPU time available.

                      D 1 Reply Last reply
                      0
                      • CPalliniC CPallini

                        Quote:

                        The problem is, if my server must send data to client, it waits 5 seconds because recv function blocks thread.

                        As far as I know, the server's send is not blocked by the client recv.

                        Quote:

                        I try to launch another thread (for each client) for send operation, but cpu works 100%.

                        Waiting on I/O operations should not consume CPU, there's probably a flawn in your code.

                        A Offline
                        A Offline
                        Albert Holguin
                        wrote on last edited by
                        #11

                        CPallini wrote:

                        As far as I know, the server's send is not blocked by the client recv.

                        They're not, unless they're on the same thread... in which case everything is blocked by the recv().

                        1 Reply Last reply
                        0
                        • A Albert Holguin

                          Daniel Pfeffer wrote:

                          IMO, a multithreaded blocking recv() implementation is conceptually much simpler than a non-blocking recv() implementation.

                          Yep, and it works really well... just be careful for hanging sockets in Linux.

                          Daniel Pfeffer wrote:

                          If you only have one physical machine, I suggest installing Windows in a virtual machine, and running one of the tasks there. That would ensure that the platforms are separate, and would help you to track down the 100% CPU issue.

                          This might actually yield the same result. The issue is the super low latency in the network when everything is co-located. Essentially if you're tx and rx run as fast as possible, it could take up all the CPU time available.

                          D Offline
                          D Offline
                          Daniel Pfeffer
                          wrote on last edited by
                          #12

                          Albert Holguin wrote:

                          This might actually yield the same result. The issue is the super low latency in the network when everything is co-located. Essentially if you're tx and rx run as fast as possible, it could take up all the CPU time available

                          I thought the problem was an optimization in the network stack that gave special treatment to packets sent to the local IP address (127.0.0.1 or the network address). In this case, the data are simply copied to the recv() buffer, without any thread switches etc. The network drivers provided by the virtual machine monitor may not be optimized to such an extent. While it is possible to detect (and optimize for) packets sent to/from the host O/S, there would be no point in it as the emulation would be less close to a separate machine. I suspect that the virtual machine monitor emulates the physical network card driver, leaving the rest of the network stack untouched.

                          If you have an important point to make, don't try to be subtle or clever. Use a pile driver. Hit the point once. Then come back and hit it again. Then hit it a third time - a tremendous whack. --Winston Churchill

                          A 1 Reply Last reply
                          0
                          • D Daniel Pfeffer

                            Albert Holguin wrote:

                            This might actually yield the same result. The issue is the super low latency in the network when everything is co-located. Essentially if you're tx and rx run as fast as possible, it could take up all the CPU time available

                            I thought the problem was an optimization in the network stack that gave special treatment to packets sent to the local IP address (127.0.0.1 or the network address). In this case, the data are simply copied to the recv() buffer, without any thread switches etc. The network drivers provided by the virtual machine monitor may not be optimized to such an extent. While it is possible to detect (and optimize for) packets sent to/from the host O/S, there would be no point in it as the emulation would be less close to a separate machine. I suspect that the virtual machine monitor emulates the physical network card driver, leaving the rest of the network stack untouched.

                            If you have an important point to make, don't try to be subtle or clever. Use a pile driver. Hit the point once. Then come back and hit it again. Then hit it a third time - a tremendous whack. --Winston Churchill

                            A Offline
                            A Offline
                            Albert Holguin
                            wrote on last edited by
                            #13

                            :doh: perhaps.... you would really only run into this issue in certain cases (where it would actually be a problem), where the data source isn't throttled and infinite (i.e. mostly test cases)

                            1 Reply Last reply
                            0
                            Reply
                            • Reply as topic
                            Log in to reply
                            • Oldest to Newest
                            • Newest to Oldest
                            • Most Votes


                            • Login

                            • Don't have an account? Register

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • World
                            • Users
                            • Groups