From b53383f6c39f40d78bfc887579e70c58f94f338a Mon Sep 17 00:00:00 2001 From: kpl Date: Wed, 12 Feb 2020 13:25:13 -0500 Subject: [PATCH] Many changes and additions to cwTcpSocket* to support MDNS and DNS-SD operations. --- cwTcpSocket.cpp | 257 +++++++++++++++++++++++++++++++------------- cwTcpSocket.h | 26 +++-- cwTcpSocketSrv.cpp | 50 ++++++--- cwTcpSocketSrv.h | 13 ++- cwTcpSocketTest.cpp | 67 ++++++++++-- cwTcpSocketTest.h | 3 +- 6 files changed, 314 insertions(+), 102 deletions(-) diff --git a/cwTcpSocket.cpp b/cwTcpSocket.cpp index 1075e08..0735272 100644 --- a/cwTcpSocket.cpp +++ b/cwTcpSocket.cpp @@ -37,6 +37,7 @@ namespace cw { int sockH; int fdH; + unsigned createFlags; unsigned flags; unsigned recvBufByteCnt; struct sockaddr_in sockaddr; @@ -140,7 +141,61 @@ namespace cw errLabel: return rc; - } + } + + rc_t _get_info( int sockH, unsigned char outBuf[6], struct sockaddr_in* addr, const char* interfaceName ) + { + cw::rc_t rc = kOkRC; + struct ifreq ifr; + struct ifconf ifc; + char buf[1024]; + + ifc.ifc_len = sizeof(buf); + ifc.ifc_buf = buf; + + if (ioctl(sockH, SIOCGIFCONF, &ifc) == -1) + { + rc = cwLogSysError(kOpFailRC,errno,"ioctl(SIOCGIFCONF) failed."); + return rc; + } + + struct ifreq* it = ifc.ifc_req; + const struct ifreq* const end = it + (ifc.ifc_len / sizeof(struct ifreq)); + + for (; it != end; ++it) + { + if( strcmp(it->ifr_name,interfaceName ) == 0 ) + { + strcpy(ifr.ifr_name, it->ifr_name); + + if (ioctl(sockH, SIOCGIFFLAGS, &ifr) != 0) + { + rc = cwLogSysError(kOpFailRC,errno,"ioctl(SIOCGIFCONF) failed."); + } + else + { + if (! (ifr.ifr_flags & IFF_LOOPBACK)) + { + // don't count loopback + if (ioctl(sockH, SIOCGIFHWADDR, &ifr) == 0) + { + memcpy(outBuf, ifr.ifr_hwaddr.sa_data, 6); + + if( addr != nullptr && ioctl(sockH, SIOCGIFADDR, &ifr) == 0) + { + addr->sin_addr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr; + } + + return kOkRC; + } + } + } + } + } + + return cwLogError(kInvalidArgRC,"The network interface information for '%s' could not be found.", interfaceName); + } + } } } @@ -152,16 +207,18 @@ cw::rc_t cw::net::socket::create( unsigned flags, unsigned timeOutMs, const char* remoteAddr, - portNumber_t remotePort ) + portNumber_t remotePort, + const char* localAddr) { rc_t rc; if((rc = destroy(hRef)) != kOkRC ) return rc; socket_t* p = mem::allocZ(); - p->sockH = cwSOCKET_NULL_SOCK; - p->fdH = cwSOCKET_NULL_SOCK; - + p->sockH = cwSOCKET_NULL_SOCK; + p->fdH = cwSOCKET_NULL_SOCK; + p->createFlags = flags; + int type = cwIsFlag(flags,kStreamFl) ? SOCK_STREAM : SOCK_DGRAM; int protocol = cwIsFlag(flags,kTcpFl) ? 0 : IPPROTO_UDP; @@ -259,11 +316,10 @@ cw::rc_t cw::net::socket::create( } } - // create the local address - if((rc = _initAddr(p, NULL, port, &p->sockaddr )) != kOkRC ) + // create the 32 bit local address + if((rc = _initAddr(p, localAddr, port, &p->sockaddr )) != kOkRC ) goto errLabel; - - + // bind the socket to a local address/port if( (bind( p->sockH, (struct sockaddr*)&p->sockaddr, sizeof(p->sockaddr))) == cwSOCKET_SYS_ERR ) { @@ -271,6 +327,11 @@ cw::rc_t cw::net::socket::create( goto errLabel; } + // get the local address as a string + if((rc = addrToString( &p->sockaddr, p->ntopBuf, sizeof(p->ntopBuf) )) != kOkRC ) + goto errLabel; + + // if a remote addr was given connect this socket to it if( remoteAddr != NULL ) if((rc = _connect(p,remoteAddr,remotePort)) != kOkRC ) @@ -310,6 +371,12 @@ cw::rc_t cw::net::socket::destroy( handle_t& hRef ) return rc; } +unsigned cw::net::socket::flags( handle_t h ) +{ + socket_t* p = _handleToPtr(h); + return p->createFlags; +} + cw::rc_t cw::net::socket::set_multicast_time_to_live( handle_t h, unsigned seconds ) { rc_t rc = kOkRC; @@ -392,8 +459,19 @@ cw::rc_t cw::net::socket::accept( handle_t h ) p->flags = cwSetFlag(p->flags,kIsConnectedFl); - printf("Connect:%s\n",s); - + /* + if( false ) + { + struct sockaddr_in addr; + char aBuf[ INET_ADDRSTRLEN+1 ]; + peername( h, &addr ); + addrToString( &addr, aBuf, INET_ADDRSTRLEN); + printf("DNS-SD PEER: %i %s\n", addr.sin_port,aBuf ); + + } + */ + + cwLogInfo("Connect:%s\n",s); } errLabel: @@ -453,7 +531,7 @@ cw::rc_t cw::net::socket::send( handle_t h, const void* data, unsigned dataByteC return send( h, data, dataByteCnt, &addr ); } -cw::rc_t cw::net::socket::recieve( handle_t h, char* data, unsigned dataByteCnt, unsigned* recvByteCntRef, struct sockaddr_in* fromAddr ) +cw::rc_t cw::net::socket::receive( handle_t h, char* data, unsigned dataByteCnt, unsigned* recvByteCntRef, struct sockaddr_in* fromAddr ) { socket_t* p = _handleToPtr(h); rc_t rc = kOkRC; @@ -468,22 +546,29 @@ cw::rc_t cw::net::socket::recieve( handle_t h, char* data, unsigned dataByteCnt, int fd = p->fdH != cwSOCKET_NULL_SOCK ? p->fdH : p->sockH; if((retVal = recvfrom(fd, data, dataByteCnt, 0, (struct sockaddr*)fromAddr, &sizeOfRemoteAddr )) == cwSOCKET_SYS_ERR ) - return errno == EAGAIN ? kTimeOutRC : cwLogSysError(kOpFailRC,errno,"recvfrom() failed."); - - - // if the read 0 bytes but did not time out this probably means that it was disconnected - if( retVal == 0 ) { - //p->flags = cwClrFlag(p->flags,kIsConnectedFl); + switch( errno ) + { + case EAGAIN: + return kTimeOutRC; + + case ENOTCONN: + if( cwIsFlag(p->flags,kIsConnectedFl ) ) + cwLogWarning("Socket Disconnected."); + + p->flags = cwClrFlag(p->flags,kIsConnectedFl); + } + + return cwLogSysError(kOpFailRC,errno,"recvfrom() failed."); } - + if( recvByteCntRef != NULL ) *recvByteCntRef = retVal; return rc; } -cw::rc_t cw::net::socket::select_recieve(handle_t h, char* buf, unsigned bufByteCnt, unsigned timeOutMs, unsigned* recvByteCntRef, struct sockaddr_in* fromAddr ) +cw::rc_t cw::net::socket::select_receive(handle_t h, char* buf, unsigned bufByteCnt, unsigned timeOutMs, unsigned* recvByteCntRef, struct sockaddr_in* fromAddr ) { rc_t rc = kOkRC; socket_t* p = _handleToPtr(h); @@ -509,7 +594,8 @@ cw::rc_t cw::net::socket::select_recieve(handle_t h, char* buf, unsigned bufByte cwLogSysError(kOpFailRC,errno,"Select failed."); break; - case 0: // select() timed out + case 0: // select() timed out + rc = kTimeOutRC; break; case 1: // (> 0) count of ready descripters @@ -522,7 +608,19 @@ cw::rc_t cw::net::socket::select_recieve(handle_t h, char* buf, unsigned bufByte // recv the incoming msg into buf[] if(( retByteCnt = recvfrom( p->sockH, buf, bufByteCnt, 0, (struct sockaddr*)fromAddr, &addrByteCnt )) == cwSOCKET_SYS_ERR ) + { + switch( errno ) + { + case ECONNRESET: + if( cwIsFlag(p->flags,kIsConnectedFl) ) + cwLogWarning("Socket Disconnected."); + p->flags = cwClrFlag(p->flags,kIsConnectedFl); + + } + rc = cwLogSysError(kOpFailRC,errno,"recvfrom() failed."); + + } else { // check for overflow @@ -579,52 +677,10 @@ cw::rc_t cw::net::socket::recv_from(handle_t h, char* buf, unsigned bufByteCnt, return rc; } -cw::rc_t cw::net::socket::get_mac( handle_t h, unsigned char outBuf[6], const char* interfaceName ) +cw::rc_t cw::net::socket::get_mac( handle_t h, unsigned char outBuf[6], struct sockaddr_in* addr, const char* netInterfaceName ) { - cw::rc_t rc = kOkRC; - socket_t* p = _handleToPtr(h); - struct ifreq ifr; - struct ifconf ifc; - char buf[1024]; - - ifc.ifc_len = sizeof(buf); - ifc.ifc_buf = buf; - - if (ioctl(p->sockH, SIOCGIFCONF, &ifc) == -1) - { - rc = cwLogSysError(kOpFailRC,errno,"ioctl(SIOCGIFCONF) failed."); - return rc; - } - - struct ifreq* it = ifc.ifc_req; - const struct ifreq* const end = it + (ifc.ifc_len / sizeof(struct ifreq)); - - for (; it != end; ++it) - { - if( strcmp(it->ifr_name,interfaceName ) == 0 ) - { - strcpy(ifr.ifr_name, it->ifr_name); - - if (ioctl(p->sockH, SIOCGIFFLAGS, &ifr) != 0) - { - rc = cwLogSysError(kOpFailRC,errno,"ioctl(SIOCGIFCONF) failed."); - } - else - { - if (! (ifr.ifr_flags & IFF_LOOPBACK)) - { - // don't count loopback - if (ioctl(p->sockH, SIOCGIFHWADDR, &ifr) == 0) - { - memcpy(outBuf, ifr.ifr_hwaddr.sa_data, 6); - return kOkRC; - } - } - } - } - } - - return cwLogError(kInvalidArgRC,"The MAC address of interface '%s' could not be found.", interfaceName); + socket_t* p = _handleToPtr(h); + return _get_info(p->sockH, outBuf, addr, netInterfaceName ); } cw::rc_t cw::net::socket::initAddr( handle_t h, const char* addrStr, portNumber_t portNumber, struct sockaddr_in* retAddrPtr ) @@ -633,18 +689,21 @@ cw::rc_t cw::net::socket::initAddr( handle_t h, const char* addrStr, portNumber_ return _initAddr(p,addrStr,portNumber,retAddrPtr); } -const char* cw::net::socket::addrToString( const struct sockaddr_in* addr, char* buf, unsigned bufN ) +cw::rc_t cw::net::socket::addrToString( const struct sockaddr_in* addr, char* buf, unsigned bufN ) { + rc_t rc = kOkRC; + errno = 0; if( inet_ntop(AF_INET, &(addr->sin_addr), buf, bufN) == NULL) { - cwLogSysError(kOpFailRC,errno, "Network address to string conversion failed." ); - return NULL; + rc = cwLogSysError(kOpFailRC,errno, "Network address to string conversion failed." ); + goto errLabel; } buf[bufN-1]=0; - return buf; + errLabel: + return rc; } bool cw::net::socket::addrIsEqual( const struct sockaddr_in* a0, const struct sockaddr_in* a1 ) @@ -662,10 +721,64 @@ const char* cw::net::socket::hostName( handle_t h ) if( gethostname(p->hnameBuf,HOST_NAME_MAX) != 0 ) { - cwLogSysError(kOpFailRC,errno, "gethostname() failed." ); - return NULL; + cwLogSysError(kOpFailRC,errno, "gethostname() failed." ); + return NULL; } p->hnameBuf[HOST_NAME_MAX] = 0; return p->hnameBuf; } + +const char* cw::net::socket::ipAddress( handle_t h ) +{ + socket_t* p = _handleToPtr(h); + return p->ntopBuf; +} + +unsigned cw::net::socket::inetAddress( handle_t h ) +{ + socket_t* p = _handleToPtr(h); + + return p->sockaddr.sin_addr.s_addr; +} + +cw::net::socket::portNumber_t cw::net::socket::port( handle_t h ) +{ + socket_t* p = _handleToPtr(h); + return ntohs(p->sockaddr.sin_port); +} + +cw::rc_t cw::net::socket::peername( handle_t h, struct sockaddr_in* addr ) +{ + rc_t rc = kOkRC; + socklen_t n = sizeof(struct sockaddr_in); + socket_t* p = _handleToPtr(h); + + if( getpeername(p->sockH, (struct sockaddr*)addr, &n) == cwSOCKET_SYS_ERR ) + return cwLogSysError(kOpFailRC,errno,"Get peer name failed."); + + addr->sin_port = ntohs(addr->sin_port); + + return rc; +} + +cw::rc_t cw::net::socket::get_info( const char* netInterfaceName, unsigned char mac[6], char* host, unsigned hostN, struct sockaddr_in* addr ) +{ + rc_t rc = kOkRC; + int sockH; + + if( host != nullptr ) + if( gethostname(host,hostN) != 0 ) + return cwLogSysError(kOpFailRC,errno,"Unable to get the local host name."); + + // get a handle to the socket + if(( sockH = ::socket( AF_INET, SOCK_DGRAM, 0 ) ) == cwSOCKET_SYS_ERR ) + return cwLogSysError(kOpFailRC,errno,"Unable to create temporary socket."); + + if((rc = _get_info(sockH,mac,addr,netInterfaceName)) != kOkRC ) + goto errLabel; + + errLabel: + close(sockH); + return rc; +} diff --git a/cwTcpSocket.h b/cwTcpSocket.h index b295d78..6e3145b 100644 --- a/cwTcpSocket.h +++ b/cwTcpSocket.h @@ -23,7 +23,7 @@ namespace cw kMultiCastTtlFl = 0x020, kMultiCastLoopFl = 0x040, kListenFl = 0x080, - kStreamFl = 0x100 + kStreamFl = 0x100, // connected stream (not Datagram) }; enum @@ -38,10 +38,13 @@ namespace cw unsigned flags, unsigned timeOutMs = 100, // time out to use with recv() on blocking sockets const char* remoteAddr = NULL, - portNumber_t remotePort = socket::kInvalidPortNumber ); - + portNumber_t remotePort = socket::kInvalidPortNumber, + const char* localAddr = NULL ); + rc_t destroy( handle_t& hRef ); + unsigned flags( handle_t h ); + rc_t set_multicast_time_to_live( handle_t h, unsigned seconds ); rc_t join_multicast_group( handle_t h, const char* addr ); @@ -77,26 +80,31 @@ namespace cw // return immediately if no incoming messages are waiting. If // recvByteCntRef is valid (non-NULL) then it is set to the // length of the received message or 0 if no msg was received. - rc_t recieve(handle_t h, char* data, unsigned dataByteCnt, unsigned* recvByteCntRef=nullptr, struct sockaddr_in* fromAddr=nullptr ); + rc_t receive(handle_t h, char* data, unsigned dataByteCnt, unsigned* recvByteCntRef=nullptr, struct sockaddr_in* fromAddr=nullptr ); // - rc_t select_recieve(handle_t h, char* buf, unsigned bufByteCnt, unsigned timeOutMs, unsigned* recvByteCntRef=nullptr, struct sockaddr_in* fromAddr=nullptr ); + rc_t select_receive(handle_t h, char* buf, unsigned bufByteCnt, unsigned timeOutMs, unsigned* recvByteCntRef=nullptr, struct sockaddr_in* fromAddr=nullptr ); // rc_t recv_from(handle_t h, char* buf, unsigned bufByteCnt, unsigned* recvByteCntRef=nullptr, struct sockaddr_in* fromAddr=nullptr ); // Note that - rc_t get_mac( handle_t h, unsigned char buf[6], const char* interfaceName=nullptr ); + rc_t get_mac( handle_t h, unsigned char buf[6], struct sockaddr_in* addr=nullptr, const char* netInterfaceName=nullptr ); // Prepare a struct sockadddr_in for use with send() rc_t initAddr( handle_t h, const char* addrStr, portNumber_t portNumber, struct sockaddr_in* retAddrPtr ); - const char* addrToString( const struct sockaddr_in* addr, char* buf, unsigned bufN=INET_ADDRSTRLEN ); + rc_t addrToString( const struct sockaddr_in* addr, char* buf, unsigned bufN=INET_ADDRSTRLEN ); bool addrIsEqual( const struct sockaddr_in* addr0, const struct sockaddr_in* addr1 ); - const char* hostName( handle_t h ); - + const char* hostName( handle_t h ); + const char* ipAddress( handle_t h ); + unsigned inetAddress( handle_t h ); + portNumber_t port( handle_t h ); + rc_t peername( handle_t h, struct sockaddr_in* addr ); + + rc_t get_info( const char* netInterfaceName, unsigned char mac[6], char* hostBuf=nullptr, unsigned hostBufN=_POSIX_HOST_NAME_MAX, struct sockaddr_in* addr=nullptr ); diff --git a/cwTcpSocketSrv.cpp b/cwTcpSocketSrv.cpp index 2e76991..3b2a6d1 100644 --- a/cwTcpSocketSrv.cpp +++ b/cwTcpSocketSrv.cpp @@ -21,6 +21,7 @@ namespace cw unsigned timeOutMs; char* recvBuf; unsigned recvBufByteCnt; + unsigned flags; } socksrv_t; inline socksrv_t* _handleToPtr( handle_t h ) { return handleToPtr(h); } @@ -43,23 +44,44 @@ namespace cw bool _threadFunc( void* arg ) { + rc_t rc = kOkRC; socksrv_t* p = static_cast(arg); unsigned rcvByteCnt = 0; struct sockaddr_in fromAddr; - rc_t rc = kOkRC; + - if( p->timeOutMs == 0 ) + if( cwIsFlag(p->flags,kUseAcceptFl) && socket::isConnected(p->sockH)==false ) { - rc = recv_from(p->sockH, p->recvBuf, p->recvBufByteCnt, &rcvByteCnt, &fromAddr ); - sleepMs(100); + rc = socket::accept( p->sockH ); } else - rc = select_recieve(p->sockH, p->recvBuf, p->recvBufByteCnt, p->timeOutMs, &rcvByteCnt, &fromAddr ); - - if( rc == kOkRC ) - if( rcvByteCnt>0 && p->cbFunc != nullptr ) - p->cbFunc( p->cbArg, p->recvBuf, rcvByteCnt, &fromAddr ); - + { + // if this is a TCP socket that is not connected + if( cwIsFlag(socket::flags( p->sockH),socket::kTcpFl) && socket::isConnected(p->sockH) == false ) + { + sleepMs(p->timeOutMs); + } + else + { + // this is a connected TCP socket or UDP socket + if( cwIsFlag(p->flags,kUseRecvFromFl) ) + { + rc = recv_from(p->sockH, p->recvBuf, p->recvBufByteCnt, &rcvByteCnt, &fromAddr ); + } + else + { + rc = select_receive(p->sockH, p->recvBuf, p->recvBufByteCnt, p->timeOutMs, &rcvByteCnt, &fromAddr ); + } + + if( (p->cbFunc != nullptr) && ((rc == kOkRC && rcvByteCnt>0) || (cwIsFlag(p->flags,kRecvTimeOutFl) && rc == kTimeOutRC))) + { + void* buf = rc == kTimeOutRC ? nullptr : p->recvBuf; + unsigned n = rc == kTimeOutRC ? 0 : rcvByteCnt; + struct sockaddr_in* addr = rc == kTimeOutRC ? nullptr : &fromAddr; + p->cbFunc( p->cbArg, buf, n, addr ); + } + } + } return true; } } @@ -70,12 +92,14 @@ cw::rc_t cw::net::srv::create( handle_t& hRef, socket::portNumber_t port, unsigned flags, + unsigned srvFlags, cbFunc_t cbFunc, void* cbArg, unsigned recvBufByteCnt, unsigned timeOutMs, const char* remoteAddr, - socket::portNumber_t remotePort ) + socket::portNumber_t remotePort, + const char* localAddr) { rc_t rc; if((rc = destroy(hRef)) != kOkRC ) @@ -83,16 +107,18 @@ cw::rc_t cw::net::srv::create( socksrv_t* p = mem::allocZ(); - if((rc = socket::create( p->sockH, port, flags, timeOutMs, remoteAddr, remotePort )) != kOkRC ) + if((rc = socket::create( p->sockH, port, flags, timeOutMs, remoteAddr, remotePort, localAddr )) != kOkRC ) goto errLabel; if((rc = thread::create( p->threadH, _threadFunc, p )) != kOkRC ) goto errLabel; + p->flags = srvFlags; p->recvBuf = mem::allocZ( recvBufByteCnt ); p->recvBufByteCnt = recvBufByteCnt; p->cbFunc = cbFunc; p->cbArg = cbArg; + p->timeOutMs = timeOutMs; errLabel: if( rc == kOkRC ) diff --git a/cwTcpSocketSrv.h b/cwTcpSocketSrv.h index 680ad84..4a98cbe 100644 --- a/cwTcpSocketSrv.h +++ b/cwTcpSocketSrv.h @@ -9,16 +9,25 @@ namespace cw { typedef void (*cbFunc_t)( void* cbArg, const void* data, unsigned dataByteCnt, const struct sockaddr_in* fromAddr ); typedef handle< struct socksrv_str > handle_t; + + enum + { + kUseAcceptFl = 0x01, // wait for a connection + kUseRecvFromFl = 0x02, // use socket::recv_from + kRecvTimeOutFl = 0x04, // Generate empty receive callbacks on receive timeouts + }; rc_t create( handle_t& hRef, // socket::portNumber_t port, // local port number - unsigned flags, // see socket::flags + unsigned flags, // see socket::flags + unsigned srvFlags, // cbFunc_t cbFunc, // callback for received messages void* cbArg, // callback arg unsigned recvBufByteCnt = 1024,// recieve buffer size unsigned timeOutMs = 100, // time out to use with recv() on thread select() const char* remoteAddr = NULL, - socket::portNumber_t remotePort = socket::kInvalidPortNumber ); + socket::portNumber_t remotePort = socket::kInvalidPortNumber, + const char* localAddr = NULL); rc_t destroy( handle_t& hRef ); diff --git a/cwTcpSocketTest.cpp b/cwTcpSocketTest.cpp index 1a0d59c..9cb468b 100644 --- a/cwTcpSocketTest.cpp +++ b/cwTcpSocketTest.cpp @@ -38,7 +38,7 @@ namespace cw char buf[ app->recvBufByteN ]; unsigned recvBufByteN = 0; - if((rc = recieve( app->sockH, buf, app->recvBufByteN, &recvBufByteN, &fromAddr )) == kOkRC ) + if((rc = receive( app->sockH, buf, app->recvBufByteN, &recvBufByteN, &fromAddr )) == kOkRC ) { addrToString( &fromAddr, addrBuf ); printf("%i %s from %s\n", recvBufByteN, buf, addrBuf ); @@ -77,7 +77,7 @@ namespace cw } else { - if((rc = recieve( app->sockH, buf, app->recvBufByteN, &recvBufByteN, nullptr )) == kOkRC ) + if((rc = receive( app->sockH, buf, app->recvBufByteN, &recvBufByteN, nullptr )) == kOkRC ) { // if the server disconnects then recvBufByteN if( !isConnected( app->sockH) ) @@ -238,19 +238,19 @@ namespace cw unsigned cbN; } app_t; - void srvRecieveCallback( void* arg, const void* data, unsigned dataByteCnt, const struct sockaddr_in* fromAddr ) + void srvReceiveCallback( void* arg, const void* data, unsigned dataByteCnt, const struct sockaddr_in* fromAddr ) { app_t* p = static_cast(arg); char addrBuf[ INET_ADDRSTRLEN ]; socket::addrToString( fromAddr, addrBuf, INET_ADDRSTRLEN ); p->cbN += 1; - printf("%i %s %s", p->cbN, addrBuf, (const char*)data ); + printf("%i %s %s\n", p->cbN, addrBuf, (const char*)data ); } } } } -cw::rc_t cw::net::srv::test( socket::portNumber_t localPort, const char* remoteAddr, socket::portNumber_t remotePort ) +cw::rc_t cw::net::srv::test_udp_srv( socket::portNumber_t localPort, const char* remoteAddr, socket::portNumber_t remotePort ) { rc_t rc; unsigned recvBufByteCnt = 1024; @@ -260,7 +260,17 @@ cw::rc_t cw::net::srv::test( socket::portNumber_t localPort, const char* remoteA app_t app; app.cbN = 0; - if((rc = srv::create(app.srvH, localPort, socket::kBlockingFl, srvRecieveCallback, &app, recvBufByteCnt, timeOutMs, NULL, socket::kInvalidPortNumber )) != kOkRC ) + if((rc = srv::create(app.srvH, + localPort, + socket::kBlockingFl, + 0, + srvReceiveCallback, + &app, + recvBufByteCnt, + timeOutMs, + nullptr, + socket::kInvalidPortNumber )) != kOkRC ) + return rc; if((rc = srv::start( app.srvH )) != kOkRC ) @@ -285,5 +295,50 @@ cw::rc_t cw::net::srv::test( socket::portNumber_t localPort, const char* remoteA return rcSelect(rc,rc0); } +cw::rc_t cw::net::srv::test_tcp_srv( socket::portNumber_t localPort, const char* remoteAddr, socket::portNumber_t remotePort ) +{ + rc_t rc; + unsigned recvBufByteCnt = 1024; + unsigned timeOutMs = 100; + const unsigned sbufN = 31; + char sbuf[ sbufN+1 ]; + app_t app; + app.cbN = 0; + + if((rc = srv::create(app.srvH, + localPort, + socket::kBlockingFl | socket::kTcpFl | socket::kStreamFl, + 0, + srvReceiveCallback, + &app, + recvBufByteCnt, + timeOutMs, + remoteAddr, + remotePort )) != kOkRC ) + + return rc; + + if((rc = srv::start( app.srvH )) != kOkRC ) + goto errLabel; + + while( true ) + { + printf("? "); + if( std::fgets(sbuf,sbufN,stdin) == sbuf ) + { + printf("Sending:%s",sbuf); + send(app.srvH, sbuf, strlen(sbuf)+1 ); + + if( strcmp(sbuf,"quit\n") == 0) + break; + } + } + + errLabel: + rc_t rc0 = destroy(app.srvH); + + return rcSelect(rc,rc0); +} + diff --git a/cwTcpSocketTest.h b/cwTcpSocketTest.h index 8352363..25bb2d9 100644 --- a/cwTcpSocketTest.h +++ b/cwTcpSocketTest.h @@ -13,7 +13,8 @@ namespace cw namespace srv { - rc_t test( socket::portNumber_t localPort, const char* remoteAddr, socket::portNumber_t remotePort ); + rc_t test_udp_srv( socket::portNumber_t localPort, const char* remoteAddr, socket::portNumber_t remotePort ); + rc_t test_tcp_srv( socket::portNumber_t localPort, const char* remoteAddr, socket::portNumber_t remotePort ); rc_t mdns_test(); } }