Many changes and additions to cwTcpSocket* to support MDNS and DNS-SD operations.
This commit is contained in:
parent
be439a8331
commit
b53383f6c3
235
cwTcpSocket.cpp
235
cwTcpSocket.cpp
@ -37,6 +37,7 @@ namespace cw
|
||||
{
|
||||
int sockH;
|
||||
int fdH;
|
||||
unsigned createFlags;
|
||||
unsigned flags;
|
||||
unsigned recvBufByteCnt;
|
||||
struct sockaddr_in sockaddr;
|
||||
@ -141,6 +142,60 @@ 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,7 +207,8 @@ 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 )
|
||||
@ -161,6 +217,7 @@ cw::rc_t cw::net::socket::create(
|
||||
socket_t* p = mem::allocZ<socket_t>();
|
||||
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,9 +459,20 @@ 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:
|
||||
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 );
|
||||
}
|
||||
|
||||
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,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;
|
||||
|
||||
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 )
|
||||
@ -483,7 +568,7 @@ cw::rc_t cw::net::socket::recieve( handle_t h, char* data, unsigned dataByteCnt,
|
||||
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);
|
||||
@ -510,6 +595,7 @@ cw::rc_t cw::net::socket::select_recieve(handle_t h, char* buf, unsigned bufByte
|
||||
break;
|
||||
|
||||
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);
|
||||
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 )
|
||||
@ -669,3 +728,57 @@ const char* cw::net::socket::hostName( handle_t h )
|
||||
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;
|
||||
}
|
||||
|
@ -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* 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 );
|
||||
|
||||
|
||||
|
||||
|
@ -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<handle_t,socksrv_t>(h); }
|
||||
@ -43,23 +44,44 @@ namespace cw
|
||||
|
||||
bool _threadFunc( void* arg )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
socksrv_t* p = static_cast<socksrv_t*>(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<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;
|
||||
|
||||
if((rc = thread::create( p->threadH, _threadFunc, p )) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
p->flags = srvFlags;
|
||||
p->recvBuf = mem::allocZ<char>( recvBufByteCnt );
|
||||
p->recvBufByteCnt = recvBufByteCnt;
|
||||
p->cbFunc = cbFunc;
|
||||
p->cbArg = cbArg;
|
||||
p->timeOutMs = timeOutMs;
|
||||
|
||||
errLabel:
|
||||
if( rc == kOkRC )
|
||||
|
@ -10,15 +10,24 @@ 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 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 );
|
||||
|
||||
|
@ -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<app_t*>(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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user