[C/Sockets] send() blockt ondanks poll()

Pagina: 1
Acties:

  • ekoopman
  • Registratie: April 2003
  • Laatst online: 28-04 09:36
Ik heb een stukje code dat ergens data vandaan haalt, dit parsed en dan doorstuurt naar een client die ermee verbonden is. Dit doe ik door een fork() waarbij de parent de data ophaalt en parsed en via een pipe doorstuurt naar de child. Deze wacht tot er data binnenkomt, kijkt dan via select() of er een client wil connecten, zo ja wordt die verbinding geaccepteerd en wordt de data via send() doorgestuurd. Dit werkt prima totdat de client disconnect, de code blijft dan hangen omdat de send() blockt. Nu heb ik mbv fcntl deze socket al op non blocking gezet, kijk met select of ik mag schrijven en doe een poll() erop maar toch blijft ie blocken. Code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
if(datasock!=-1)
{
  //check if we can send to datasock
  tv.tv_sec=0;
  tv.tv_usec=0;       
  tempfdset=master;
  if((nsel=select(fdmax+1, NULL, &tempfdset, NULL, &tv))==-1)
  {
    fprintf(stderr, "Failure selecting\n");
  }       
  if(FD_ISSET(datasock, &tempfdset))
  {
    printf("Start send %d\n",nsel); //nsel is hier altijd 1
    pollset.fd=datasock;
    pollset.events=POLLOUT;
    printf("poll%d\n", poll(&pollset, 1, 100));//Dit print ook netjes 1
    if(send(datasock, framebuffer, nbytes, 0)==-1)//Deze functie call blockt dus
    {
      printf("\nD'oh! Failure sending\n");
    }
    printf("End send\n");
    }
    else
    {
      printf("cant send to datasock\n");
    }
  }
}

Iemand enig idee wat ik verkeerd doe dus?

[ Voor 6% gewijzigd door ekoopman op 21-08-2005 14:44 ]


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

als ik het goed begrijp probeert je server nog data door te zenden wanneer je client al close() gedaan heeft ? probeer dan even de functie shutdown() uit.

uit MSDN:
If no buffer space is available within the transport system to hold the data to be transmitted, send will block unless the socket has been placed in a nonblocking mode. On nonblocking stream oriented sockets, the number of bytes written can be between 1 and the requested length, depending on buffer availability on both client and server machines. The select, WSAAsyncSelect or WSAEventSelect functions can be used to determine when it is possible to send more data.
de zendbuffer loopt dus blijkbaar vol. gebruik dus shutdown of controleer of de client de verbinding niet al gesloten heeft dmv recv()

ASSUME makes an ASS out of U and ME


  • ekoopman
  • Registratie: April 2003
  • Laatst online: 28-04 09:36
Bedankt :D, aan die msdn info heb ik niet zoveel (linux), maar checken door recv() te doen op die socket lijkt te werken, die retourneert de hele tijd -1 totdat de client disconnect, dan krijg ik 0.

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

de implementatie in linux en Windows voor die functies is "gelijk"
maw je Linux netwerk code loopt 95% zeker gelijk op windows en omgekeerd.

ASSUME makes an ASS out of U and ME


  • igmar
  • Registratie: April 2000
  • Laatst online: 20-04 22:06

igmar

ISO20022

Kroxigor schreef op zondag 21 augustus 2005 @ 14:43:
Dit werkt prima totdat de client disconnect, de code blijft dan hangen omdat de send() blockt. Nu heb ik mbv fcntl deze socket al op non blocking gezet, kijk met select of ik mag schrijven en doe een poll() erop maar toch blijft ie blocken.
send verschijnt altijd in select(), tenzij de kernel buffers vol zijn, hetgeen eigenlijk nooit voorkomt. Indien non-blocking niet werk ligt dat aan jouw code, waarschijnlijk omdat je de non-blocking fcntl() op het verkeerde moment doet.

Verder moet je er rekening mee houden dat zowel send() als recv() 0 kunnen retourneren : Dat moet je opvatten als EOF. Dat levert dus voor de duidelijkheid geen -1 returncode op.

  • ShadowLord
  • Registratie: Juli 2000
  • Laatst online: 02-05 16:14
Zoals ik het zie is de enige reden dat je non-blocking werkt omdat je socket ander blijft hangen? Dit is een slechte motivatie om dit te doen an kan ik dan ook niet aanraden. Non-blocking sockets brengen een mega-stapel aan problemen mee als je niet weet wat je doet.

Met select kun je de lees, schrijf en error status van de socket afvragen.je vergeet in jou code de error-status af te vragen. Probeer dit eens, je zal dan waarschijnlijk wel een melding krijgen dat de sochet is gesloten. Kijk ook beter naar de returnwaarden van send (niet alleen tegen -1 checken). Als deze namelijk niet overeenkomt met de te verzenden hoeveelheid data weet je dat er iets mis is (en kun je deze fout dus afvragen).

You see things; and you say, "Why?" But I dream things that never were; and I say, "Why not?"

Pagina: 1