c - When I turn O_NONBLOCK on i get "0" and "I/O error" -
when turn on o_nonblock
connection len returns 0
, errno returns eio
. expecting len -1
, errno eagain
. based on getting can assume there problem initial connection. don't understand why getting it. if comment out turn on o_nonblock
not have issue @ all. missing in regards turning on o_nonblcok
?
my code (main())
long len; //var o_nonblocking int flags; printf("r thread - starting\n"); maintcpipindex = tcpipindex = 0; while ( fmainshutdown == false ) { s_muxwait(5000, "", &hevtcpipbuffavail[maintcpipindex], 0); if ( hevtcpipbuffavail[maintcpipindex] == 0) continue; len = s_recv( lsocket, tcpiprecord[maintcpipindex].tcpipbuffer, sizeof(tcpiprecord[maintcpipindex].tcpipbuffer)); //initialize flags var flags = fcntl(lsocket, f_getfl, 0); //turns on o_nonblocking fcntl(lsocket, f_setfl, flags | o_nonblock); if (len == -1 || len == 0 && errno != eagain) //0 = connection broken host { receiveerror = errno; hevreceiveerror = 1; printf("r_main - set hevreceiveerror on\n"); pthread_exit(null); } //catches o_nonblock if (len == -1 && errno == eagain) { logmessage(&logstruct, info, logqueue + logscreen, "caught o_nonblocking\n"); len = 0; continue; } // record length tcpiprecord[maintcpipindex].ultcpipbuflen = len; // tell t thread have message hevtcpipbuffused[maintcpipindex] = 1; hevtcpipbuffavail[maintcpipindex] = 0; // maintain index if ( ++maintcpipindex >= max_tcpip_buffs ) maintcpipindex = 0; }//end while
edit
maybe did not create clear first time, understand errno , len has s_recv
issue getting undesired results when turn on o_nonblock; s_recv
's errno eio , len 0. if turn turn off o_nonblock
of issues go away; len 1 or more , errno not need checked.
below illustration of th scenarios expect:
in first bad scenario s_recv
's len 0 or -1, errno not eagain, , connection reset.
in sec bad sceanrio s_recv
's len -1 , errno eagain. exepected scenario when o_nonblock turned on based off man pages.
in sceanrio s_recv
's len more 1 , there no need check errno.
the alter o_nonblock
not relevant before next read.
so, must check len
, errno
before phone call fcntl
. , must check homecoming value of fcntl
of course, because might fail well.
to summarize, len == 0
, errno == eio
has nil alter o_nonblock
, s_recv
before.
additionally, aware
if (len == -1 || len == 0 && errno != eagain)
is same
if (len == -1 || (len == 0 && errno != eagain) )
which not meaningful, because if homecoming value not -1
, errno must ignored. if homecoming value 0
, peer has closed connection.
update:
i've built simple echo client
fd = socket(af_inet, sock_stream, 0); if (fd == -1) error("socket"); = gethostbyname("localhost"); memset(&addr, 0, sizeof(addr)); addr.sin_family = af_inet; addr.sin_addr.s_addr = ((struct in_addr*)he->h_addr)->s_addr; addr.sin_port = htons(7); /* echo */ if (connect(fd, (struct sockaddr*) &addr, sizeof(addr)) == -1) error("connect"); while (fgets(buf, sizeof(buf), stdin)) { n = strlen(buf); printf("fgets=%d, %s", n, buf); if (send(fd, buf, n, 0) == -1) error("send"); n = recv(fd, buf, sizeof(buf), 0); if (n == -1) error("recv"); printf("recv=%d, %s", n, buf); flags = fcntl(fd, f_getfl, 0); printf("flags=%d\n", flags); if (fcntl(fd, f_setfl, flags | o_nonblock) == -1) error("fcntl"); }
and after setting o_nonblock
, receive
errno=11 recv: resource temporarily unavailable
if move fcntl(o_nonblock)
before loop, works fine.
so, seems not advisable fiddle non blocking after reading or writing socket.
c linux tcp redhat
No comments:
Post a Comment