Many changes and additions to cwTcpSocket* to support MDNS and DNS-SD operations.

This commit is contained in:
kpl 2020-02-12 13:25:13 -05:00
parent be439a8331
commit b53383f6c3
6 changed files with 314 additions and 102 deletions

View File

@ -37,6 +37,7 @@ namespace cw
{ {
int sockH; int sockH;
int fdH; int fdH;
unsigned createFlags;
unsigned flags; unsigned flags;
unsigned recvBufByteCnt; unsigned recvBufByteCnt;
struct sockaddr_in sockaddr; struct sockaddr_in sockaddr;
@ -141,6 +142,60 @@ namespace cw
errLabel: errLabel:
return rc; 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,7 +207,8 @@ cw::rc_t cw::net::socket::create(
unsigned flags, unsigned flags,
unsigned timeOutMs, unsigned timeOutMs,
const char* remoteAddr, const char* remoteAddr,
portNumber_t remotePort ) portNumber_t remotePort,
const char* localAddr)
{ {
rc_t rc; rc_t rc;
if((rc = destroy(hRef)) != kOkRC ) if((rc = destroy(hRef)) != kOkRC )
@ -161,6 +217,7 @@ cw::rc_t cw::net::socket::create(
socket_t* p = mem::allocZ<socket_t>(); socket_t* p = mem::allocZ<socket_t>();
p->sockH = cwSOCKET_NULL_SOCK; p->sockH = cwSOCKET_NULL_SOCK;
p->fdH = cwSOCKET_NULL_SOCK; p->fdH = cwSOCKET_NULL_SOCK;
p->createFlags = flags;
int type = cwIsFlag(flags,kStreamFl) ? SOCK_STREAM : SOCK_DGRAM; int type = cwIsFlag(flags,kStreamFl) ? SOCK_STREAM : SOCK_DGRAM;
int protocol = cwIsFlag(flags,kTcpFl) ? 0 : IPPROTO_UDP; int protocol = cwIsFlag(flags,kTcpFl) ? 0 : IPPROTO_UDP;
@ -259,11 +316,10 @@ cw::rc_t cw::net::socket::create(
} }
} }
// create the local address // create the 32 bit local address
if((rc = _initAddr(p, NULL, port, &p->sockaddr )) != kOkRC ) if((rc = _initAddr(p, localAddr, port, &p->sockaddr )) != kOkRC )
goto errLabel; goto errLabel;
// bind the socket to a local address/port // bind the socket to a local address/port
if( (bind( p->sockH, (struct sockaddr*)&p->sockaddr, sizeof(p->sockaddr))) == cwSOCKET_SYS_ERR ) 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; 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 a remote addr was given connect this socket to it
if( remoteAddr != NULL ) if( remoteAddr != NULL )
if((rc = _connect(p,remoteAddr,remotePort)) != kOkRC ) if((rc = _connect(p,remoteAddr,remotePort)) != kOkRC )
@ -310,6 +371,12 @@ cw::rc_t cw::net::socket::destroy( handle_t& hRef )
return rc; 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 ) cw::rc_t cw::net::socket::set_multicast_time_to_live( handle_t h, unsigned seconds )
{ {
rc_t rc = kOkRC; rc_t rc = kOkRC;
@ -392,9 +459,20 @@ cw::rc_t cw::net::socket::accept( handle_t h )
p->flags = cwSetFlag(p->flags,kIsConnectedFl); 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: errLabel:
return rc; return rc;
@ -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 ); 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); socket_t* p = _handleToPtr(h);
rc_t rc = kOkRC; rc_t rc = kOkRC;
@ -468,13 +546,20 @@ 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; 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 ) 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 ) if( recvByteCntRef != NULL )
@ -483,7 +568,7 @@ cw::rc_t cw::net::socket::recieve( handle_t h, char* data, unsigned dataByteCnt,
return rc; 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; rc_t rc = kOkRC;
socket_t* p = _handleToPtr(h); socket_t* p = _handleToPtr(h);
@ -510,6 +595,7 @@ cw::rc_t cw::net::socket::select_recieve(handle_t h, char* buf, unsigned bufByte
break; break;
case 0: // select() timed out case 0: // select() timed out
rc = kTimeOutRC;
break; break;
case 1: // (> 0) count of ready descripters 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[] // recv the incoming msg into buf[]
if(( retByteCnt = recvfrom( p->sockH, buf, bufByteCnt, 0, (struct sockaddr*)fromAddr, &addrByteCnt )) == cwSOCKET_SYS_ERR ) 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."); rc = cwLogSysError(kOpFailRC,errno,"recvfrom() failed.");
}
else else
{ {
// check for overflow // check for overflow
@ -579,52 +677,10 @@ cw::rc_t cw::net::socket::recv_from(handle_t h, char* buf, unsigned bufByteCnt,
return rc; 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); socket_t* p = _handleToPtr(h);
struct ifreq ifr; return _get_info(p->sockH, outBuf, addr, netInterfaceName );
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);
} }
cw::rc_t cw::net::socket::initAddr( handle_t h, const char* addrStr, portNumber_t portNumber, struct sockaddr_in* retAddrPtr ) 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); 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; errno = 0;
if( inet_ntop(AF_INET, &(addr->sin_addr), buf, bufN) == NULL) if( inet_ntop(AF_INET, &(addr->sin_addr), buf, bufN) == NULL)
{ {
cwLogSysError(kOpFailRC,errno, "Network address to string conversion failed." ); rc = cwLogSysError(kOpFailRC,errno, "Network address to string conversion failed." );
return NULL; goto errLabel;
} }
buf[bufN-1]=0; buf[bufN-1]=0;
return buf; errLabel:
return rc;
} }
bool cw::net::socket::addrIsEqual( const struct sockaddr_in* a0, const struct sockaddr_in* a1 ) bool cw::net::socket::addrIsEqual( const struct sockaddr_in* a0, const struct sockaddr_in* a1 )
@ -669,3 +728,57 @@ const char* cw::net::socket::hostName( handle_t h )
p->hnameBuf[HOST_NAME_MAX] = 0; p->hnameBuf[HOST_NAME_MAX] = 0;
return p->hnameBuf; 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;
}

View File

@ -23,7 +23,7 @@ namespace cw
kMultiCastTtlFl = 0x020, kMultiCastTtlFl = 0x020,
kMultiCastLoopFl = 0x040, kMultiCastLoopFl = 0x040,
kListenFl = 0x080, kListenFl = 0x080,
kStreamFl = 0x100 kStreamFl = 0x100, // connected stream (not Datagram)
}; };
enum enum
@ -38,10 +38,13 @@ namespace cw
unsigned flags, unsigned flags,
unsigned timeOutMs = 100, // time out to use with recv() on blocking sockets unsigned timeOutMs = 100, // time out to use with recv() on blocking sockets
const char* remoteAddr = NULL, const char* remoteAddr = NULL,
portNumber_t remotePort = socket::kInvalidPortNumber ); portNumber_t remotePort = socket::kInvalidPortNumber,
const char* localAddr = NULL );
rc_t destroy( handle_t& hRef ); 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 set_multicast_time_to_live( handle_t h, unsigned seconds );
rc_t join_multicast_group( handle_t h, const char* addr ); 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 // return immediately if no incoming messages are waiting. If
// recvByteCntRef is valid (non-NULL) then it is set to the // recvByteCntRef is valid (non-NULL) then it is set to the
// length of the received message or 0 if no msg was received. // 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 ); rc_t recv_from(handle_t h, char* buf, unsigned bufByteCnt, unsigned* recvByteCntRef=nullptr, struct sockaddr_in* fromAddr=nullptr );
// Note that // 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() // 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 ); 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 ); 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 );

View File

@ -21,6 +21,7 @@ namespace cw
unsigned timeOutMs; unsigned timeOutMs;
char* recvBuf; char* recvBuf;
unsigned recvBufByteCnt; unsigned recvBufByteCnt;
unsigned flags;
} socksrv_t; } socksrv_t;
inline socksrv_t* _handleToPtr( handle_t h ) { return handleToPtr<handle_t,socksrv_t>(h); } inline socksrv_t* _handleToPtr( handle_t h ) { return handleToPtr<handle_t,socksrv_t>(h); }
@ -43,23 +44,44 @@ namespace cw
bool _threadFunc( void* arg ) bool _threadFunc( void* arg )
{ {
rc_t rc = kOkRC;
socksrv_t* p = static_cast<socksrv_t*>(arg); socksrv_t* p = static_cast<socksrv_t*>(arg);
unsigned rcvByteCnt = 0; unsigned rcvByteCnt = 0;
struct sockaddr_in fromAddr; 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 ); rc = socket::accept( p->sockH );
sleepMs(100);
} }
else else
rc = select_recieve(p->sockH, p->recvBuf, p->recvBufByteCnt, p->timeOutMs, &rcvByteCnt, &fromAddr ); {
// if this is a TCP socket that is not connected
if( rc == kOkRC ) if( cwIsFlag(socket::flags( p->sockH),socket::kTcpFl) && socket::isConnected(p->sockH) == false )
if( rcvByteCnt>0 && p->cbFunc != nullptr ) {
p->cbFunc( p->cbArg, p->recvBuf, rcvByteCnt, &fromAddr ); 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; return true;
} }
} }
@ -70,12 +92,14 @@ cw::rc_t cw::net::srv::create(
handle_t& hRef, handle_t& hRef,
socket::portNumber_t port, socket::portNumber_t port,
unsigned flags, unsigned flags,
unsigned srvFlags,
cbFunc_t cbFunc, cbFunc_t cbFunc,
void* cbArg, void* cbArg,
unsigned recvBufByteCnt, unsigned recvBufByteCnt,
unsigned timeOutMs, unsigned timeOutMs,
const char* remoteAddr, const char* remoteAddr,
socket::portNumber_t remotePort ) socket::portNumber_t remotePort,
const char* localAddr)
{ {
rc_t rc; rc_t rc;
if((rc = destroy(hRef)) != kOkRC ) if((rc = destroy(hRef)) != kOkRC )
@ -83,16 +107,18 @@ cw::rc_t cw::net::srv::create(
socksrv_t* p = mem::allocZ<socksrv_t>(); socksrv_t* p = mem::allocZ<socksrv_t>();
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; goto errLabel;
if((rc = thread::create( p->threadH, _threadFunc, p )) != kOkRC ) if((rc = thread::create( p->threadH, _threadFunc, p )) != kOkRC )
goto errLabel; goto errLabel;
p->flags = srvFlags;
p->recvBuf = mem::allocZ<char>( recvBufByteCnt ); p->recvBuf = mem::allocZ<char>( recvBufByteCnt );
p->recvBufByteCnt = recvBufByteCnt; p->recvBufByteCnt = recvBufByteCnt;
p->cbFunc = cbFunc; p->cbFunc = cbFunc;
p->cbArg = cbArg; p->cbArg = cbArg;
p->timeOutMs = timeOutMs;
errLabel: errLabel:
if( rc == kOkRC ) if( rc == kOkRC )

View File

@ -10,15 +10,24 @@ namespace cw
typedef void (*cbFunc_t)( void* cbArg, const void* data, unsigned dataByteCnt, const struct sockaddr_in* fromAddr ); typedef void (*cbFunc_t)( void* cbArg, const void* data, unsigned dataByteCnt, const struct sockaddr_in* fromAddr );
typedef handle< struct socksrv_str > handle_t; 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, // rc_t create( handle_t& hRef, //
socket::portNumber_t port, // local port number 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 cbFunc_t cbFunc, // callback for received messages
void* cbArg, // callback arg void* cbArg, // callback arg
unsigned recvBufByteCnt = 1024,// recieve buffer size unsigned recvBufByteCnt = 1024,// recieve buffer size
unsigned timeOutMs = 100, // time out to use with recv() on thread select() unsigned timeOutMs = 100, // time out to use with recv() on thread select()
const char* remoteAddr = NULL, 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 ); rc_t destroy( handle_t& hRef );

View File

@ -38,7 +38,7 @@ namespace cw
char buf[ app->recvBufByteN ]; char buf[ app->recvBufByteN ];
unsigned recvBufByteN = 0; 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 ); addrToString( &fromAddr, addrBuf );
printf("%i %s from %s\n", recvBufByteN, buf, addrBuf ); printf("%i %s from %s\n", recvBufByteN, buf, addrBuf );
@ -77,7 +77,7 @@ namespace cw
} }
else 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 the server disconnects then recvBufByteN
if( !isConnected( app->sockH) ) if( !isConnected( app->sockH) )
@ -238,19 +238,19 @@ namespace cw
unsigned cbN; unsigned cbN;
} app_t; } 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<app_t*>(arg); app_t* p = static_cast<app_t*>(arg);
char addrBuf[ INET_ADDRSTRLEN ]; char addrBuf[ INET_ADDRSTRLEN ];
socket::addrToString( fromAddr, addrBuf, INET_ADDRSTRLEN ); socket::addrToString( fromAddr, addrBuf, INET_ADDRSTRLEN );
p->cbN += 1; 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; rc_t rc;
unsigned recvBufByteCnt = 1024; 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_t app;
app.cbN = 0; 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; return rc;
if((rc = srv::start( app.srvH )) != kOkRC ) 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); 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);
}

View File

@ -13,7 +13,8 @@ namespace cw
namespace srv 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(); rc_t mdns_test();
} }
} }