i'm working on legacy vc6 application, uses winsocket listen udp port incoming packets. getting following errors. if use wsagetlasterror()
wsaeconnreset
, if read description, doesn't seem make sense, because saying remote host forcibly closed socket, want use udp connection-less manor, shouldn't matter other machine doing... should listen. if check errno
, use sterror()
following message. "no such file or directory"
. (i think it's enum eio, according http://pubs.opengroup.org/onlinepubs/009695399/functions/recvfrom.html)
i've had success in narrowing down issue, appears if take out sendto()
call, calls on same port recvfrom()
, code seems work ok. sendto()
putting in bad state.
i'm looking suggestions on why socket going bad, , either how prevent or recover.
edit
here other weird part, if setup again socket (after recvfrom() fails)... seems work, additional calls sendto()
don't seem trigger recvfrom() fail, in turn call setup again..
code
static void setupsocketaddress( sockaddr_u &sarx, int nrtdport ) { memset(&sarx.saipx, 0, sizeof(sockaddr_ipx)); sarx.saipx.sa_family = af_ipx; // ipx type address memset(sarx.saipx.sa_netnum,0x00,4); // may have number memset(sarx.saipx.sa_nodenum,0xff,6); // broadcast address sarx.saipx.sa_socket=(unsigned short)nrtdport; // socket number } void crealtimedata::setupsocket( crealtimedata * lprtd, bool &bdone, sockaddr_u &sarx, int nrtdport, sockaddr_u &safrom, int &cbaddr, dword &dwlocaladdress, int &nmaxipipxbuf, char * &pbyipipxrxbuf, int nflags, bool bdo) { char szerrorcode[32]; int nreturn = 0; if (lprtd->m_esourcetype == v7_rtd_ipx) { // open ipx socket // packet type = 4 lprtd->m_socket=socket(af_ipx, sock_dgram, nsproto_ipx+4); if (lprtd->m_socket == invalid_socket) { nreturn = addsocketerrortoeventviewer( lprtd); bdone = true; } // socket must bound prior calling recvfrom() // setup address setupsocketaddress(sarx, nrtdport); #ifdef _debug_ipx // test changing host number network number // can't change though, because other programs use way u_short nnetport=0; int nret=wsahtons(lprtd->m_socket, (unsigned short)nrtdport, &nnetport); trace(_t("rtdipxthread: host port=%04x net port=%04x rtd input=%d \n"),nrtdport, nnetport, lprtd->getinputnumber()); #endif // setup address sending data on rtd setupsocketaddress( lprtd->m_sartd, nrtdport ); // copy address - why copying address on right later (in recvfrom() )? -ng memcpy(&safrom.saipx, &lprtd->m_sartd.saipx, sizeof(sockaddr_ipx)); cbaddr = sizeof(sockaddr_ipx); } else { // open ip socket lprtd->m_socket=socket(af_inet, sock_dgram, ipproto_ip); // ??? should use ipproto_udp??? if (lprtd->m_socket == invalid_socket) { nreturn = addsocketerrortoeventviewer( lprtd); bdone = true; } // socket must bound prior calling recvfrom() // setup address memset(&sarx.saip, 0, sizeof(sockaddr_in)); sarx.saip.sin_family = af_inet; // ip type address sarx.saip.sin_port=htons((u_short)nrtdport); // port number sarx.saip.sin_addr.s_addr=htonl(inaddr_any); // address number // setup sending data on rtd port memset(&lprtd->m_sartd.saip, 0, sizeof(sockaddr_in)); lprtd->m_sartd.saip.sin_family = af_inet; // ip type address lprtd->m_sartd.saip.sin_port=htons((u_short)nrtdport); // port number lprtd->m_sartd.saip.sin_addr.s_addr=htonl(inaddr_broadcast); // address number // copy address - why copying address on right later (in recvfrom() )? -ng memcpy(&safrom.saip, &lprtd->m_sartd.saip, sizeof(sockaddr_in)); cbaddr = sizeof(sockaddr_in); char szhostname[max_path+1]; if (gethostname(szhostname, max_path)==0) { hostent *phe=gethostbyname(szhostname); dwlocaladdress = *(dword*)&phe->h_addr_list[0]; } } // end ip socket if (!bdone) { // enable broadcasting bool boptval=true; nreturn=setsockopt(lprtd->m_socket, sol_socket, so_broadcast, (char *)&boptval, sizeof(bool)); if (nreturn == socket_error) { nreturn=wsagetlasterror(); } // enable reuse of address boptval=true; nreturn=setsockopt(lprtd->m_socket, sol_socket, so_reuseaddr, (char *)&boptval, sizeof(bool)); if (nreturn == socket_error) { nreturn=wsagetlasterror(); } // socket's max message size int noptsize=sizeof(uint); uint nmaxmsgsize=600; nreturn=getsockopt(lprtd->m_socket, sol_socket, so_max_msg_size, (char *)&nmaxmsgsize, &noptsize); if (nreturn == socket_error) { nreturn=wsagetlasterror(); nmaxmsgsize=600; // default max size } nmaxipipxbuf=nmaxmsgsize; // create buffer big sockets max message size pbyipipxrxbuf = new char[nmaxipipxbuf]; // allocate buffer receiving data socket if (!pbyipipxrxbuf) bdone = true; else memset(pbyipipxrxbuf,0,nmaxipipxbuf*sizeof(char)); // bind address nreturn=bind(lprtd->m_socket, &sarx.sa, cbaddr); if (nreturn == socket_error) { nreturn = addsocketerrortoeventviewer(lprtd); bdone = true; } // send data indicate startup if (lprtd->m_eprotocol == v7_rtd_enhanced) { int nlen=lprtd->builderrormsg(v7_ertd_service_startup, szerrorcode, sizeof(szerrorcode)); nreturn=sendto(lprtd->m_socket,szerrorcode,nlen, nflags, &lprtd->m_sartd.sa, cbaddr); if (nreturn == socket_error) { nreturn=wsagetlasterror(); } } } // end if not done }
main()
nfromlen = cbaddr; nreturn=recvfrom(lprtd->m_socket, pbyipipxrxbuf, nmaxipipxbuf, nflags, &safrom.sa, &nfromlen); if(nreturn == socket_error) { setupsocket(lprtd, bdone, sarx, nrtdport, safrom, cbaddr, dwlocaladdress, nmaxipipxbuf, pbyipipxrxbuf,nflags, false); nreturn=recvfrom(lprtd->m_socket, pbyipipxrxbuf, nmaxipipxbuf, nflags, &safrom.sa, &nfromlen); } // if take out no error.... nreturn=sendto(lprtd->m_socket, szerrorcode, nlen, nflags, &safrom.sa, cbaddr);
Comments
Post a Comment