Friday, 15 March 2013

c - When I turn O_NONBLOCK on i get "0" and "I/O error" -



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