📄 gsocket.c
字号:
int ret = -1;
#if 0
struct sockaddr from;
WX_SOCKLEN_T fromlen = sizeof(from);
GSocketError err;
fromlen = sizeof(from);
ret = recvfrom(socket->m_endpoint, buffer, size, 0, &from, (WX_SOCKLEN_T *) &fromlen);
if (ret == -1)
return -1;
/* Translate a system address into a GSocket address */
if (!socket->m_peer)
{
socket->m_peer = GAddress_new();
if (!socket->m_peer)
{
socket->m_error = GSOCK_MEMERR;
return -1;
}
}
err = _GAddress_translate_from(socket->m_peer, &from, fromlen);
if (err != GSOCK_NOERROR)
{
GAddress_destroy(socket->m_peer);
socket->m_peer = NULL;
socket->m_error = err;
return -1;
}
#endif
return ret;
}
int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
{
OTFlags flags = 0 ;
OTResult res ;
res = OTSnd( socket->m_endpoint , (void*) buffer , size , flags ) ;
return res ;
}
int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
{
int ret = -1 ;
// TODO
#if 0
struct sockaddr *addr;
int len ;
GSocketError err;
if (!socket->m_peer)
{
socket->m_error = GSOCK_INVADDR;
return -1;
}
err = _GAddress_translate_to(socket->m_peer, &addr, &len);
if (err != GSOCK_NOERROR)
{
socket->m_error = err;
return -1;
}
ret = sendto(socket->m_endpoint, buffer, size, 0, addr, len);
/* Frees memory allocated from _GAddress_translate_to */
free(addr);
#endif
return ret;
}
/*
* -------------------------------------------------------------------------
* GAddress
* -------------------------------------------------------------------------
*/
/* CHECK_ADDRESS verifies that the current family is either GSOCK_NOFAMILY
* or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it initalizes address
* to be a GSOCK_*family*. In other cases, it returns GSOCK_INVADDR.
*/
#define CHECK_ADDRESS(address, family, retval) \
{ \
if (address->m_family == GSOCK_NOFAMILY) \
if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
return address->m_error; \
if (address->m_family != GSOCK_##family) \
{ \
address->m_error = GSOCK_INVADDR; \
return retval; \
} \
}
GAddress *GAddress_new()
{
GAddress *address;
if ((address = (GAddress *) malloc(sizeof(GAddress))) == NULL)
return NULL;
address->m_family = GSOCK_NOFAMILY;
address->m_host = INADDR_NONE ;
address->m_port = 0 ;
return address;
}
GAddress *GAddress_copy(GAddress *address)
{
GAddress *addr2;
assert(address != NULL);
if ((addr2 = (GAddress *) malloc(sizeof(GAddress))) == NULL)
return NULL;
memcpy(addr2, address, sizeof(GAddress));
return addr2;
}
void GAddress_destroy(GAddress *address)
{
assert(address != NULL);
free(address);
}
void GAddress_SetFamily(GAddress *address, GAddressType type)
{
assert(address != NULL);
address->m_family = type;
}
GAddressType GAddress_GetFamily(GAddress *address)
{
assert(address != NULL);
return address->m_family;
}
GSocketError _GAddress_translate_from(GAddress *address,
InetAddress *addr)
{
switch (addr->fAddressType)
{
case AF_INET:
address->m_family = GSOCK_INET;
break;
#ifdef AF_INET6
case AF_INET6:
address->m_family = GSOCK_INET6;
break;
#endif
default:
{
address->m_error = GSOCK_INVOP;
return GSOCK_INVOP;
}
}
address->m_host = addr->fHost ;
address->m_port = addr->fPort ;
return GSOCK_NOERROR;
}
GSocketError _GAddress_translate_to(GAddress *address,
InetAddress *addr)
{
if ( GSocket_Verify_Inited() == FALSE )
return GSOCK_IOERR ;
memset(addr, 0 , sizeof(struct InetAddress));
OTInitInetAddress( addr , address->m_port , address->m_host ) ;
return GSOCK_NOERROR;
}
/*
* -------------------------------------------------------------------------
* Internet address family
* -------------------------------------------------------------------------
*/
GSocketError _GAddress_Init_INET(GAddress *address)
{
address->m_family = GSOCK_INET;
address->m_host = kOTAnyInetAddress ;
return GSOCK_NOERROR;
}
GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
{
InetHostInfo hinfo ;
OSStatus ret ;
if ( GSocket_Verify_Inited() == FALSE )
return GSOCK_IOERR ;
assert(address != NULL);
CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
ret = OTInetStringToAddress( gInetSvcRef , (char*) hostname , &hinfo ) ;
if ( ret != kOTNoError )
{
address->m_host = INADDR_NONE ;
address->m_error = GSOCK_NOHOST;
return GSOCK_NOHOST;
}
address->m_host = hinfo.addrs[0] ;
return GSOCK_NOERROR;
}
GSocketError GAddress_INET_SetAnyAddress(GAddress *address)
{
return GAddress_INET_SetHostAddress(address, INADDR_ANY);
}
GSocketError GAddress_INET_SetHostAddress(GAddress *address,
unsigned long hostaddr)
{
assert(address != NULL);
CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
address->m_host = hostaddr ;
return GSOCK_NOERROR;
}
struct service_entry
{
char * name ;
unsigned short port ;
char * protocol ;
} ;
typedef struct service_entry service_entry ;
service_entry gServices[] =
{
{ "http" , 80 , "tcp" }
} ;
GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
const char *protocol)
{
size_t i ;
assert(address != NULL);
CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
if (!port)
{
address->m_error = GSOCK_INVPORT;
return GSOCK_INVPORT;
}
for ( i = 0 ; i < sizeof( gServices) / sizeof( service_entry ) ; ++i )
{
if ( strcmp( port , gServices[i].name ) == 0 )
{
if ( protocol == NULL || strcmp( protocol , gServices[i].protocol ) )
{
address->m_port = gServices[i].port ;
return GSOCK_NOERROR;
}
}
}
if (isdigit(port[0]))
{
address->m_port = atoi(port);
return GSOCK_NOERROR;
}
address->m_error = GSOCK_INVPORT;
return GSOCK_INVPORT;
}
GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
{
assert(address != NULL);
CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
address->m_port = port ;
return GSOCK_NOERROR;
}
GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
{
InetDomainName name ;
if ( GSocket_Verify_Inited() == FALSE )
return GSOCK_IOERR ;
assert(address != NULL);
CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
OTInetAddressToName( gInetSvcRef , address->m_host , name ) ;
strncpy( hostname , name , sbuf ) ;
return GSOCK_NOERROR;
}
unsigned long GAddress_INET_GetHostAddress(GAddress *address)
{
assert(address != NULL);
CHECK_ADDRESS(address, INET, 0);
return address->m_host;
}
unsigned short GAddress_INET_GetPort(GAddress *address)
{
assert(address != NULL);
CHECK_ADDRESS(address, INET, 0);
return address->m_port;
}
void _GSocket_Enable_Events(GSocket *socket)
{
if ( socket->m_takesEvents )
return ;
{
OTResult state ;
socket->m_takesEvents = TRUE ;
state = OTGetEndpointState(socket->m_endpoint);
{
OTByteCount sz = 0 ;
OTCountDataBytes( socket->m_endpoint , &sz ) ;
if ( state == T_INCON || sz > 0 )
{
socket->m_detected |= GSOCK_INPUT_FLAG ;
(socket->m_cbacks[GSOCK_INPUT])(socket, GSOCK_INPUT, socket->m_data[GSOCK_INPUT]);
}
}
{
if ( state == T_DATAXFER || state == T_INREL )
{
socket->m_detected |=GSOCK_OUTPUT_FLAG ;
(socket->m_cbacks[GSOCK_OUTPUT])(socket, GSOCK_OUTPUT, socket->m_data[GSOCK_OUTPUT]);
}
}
}
}
void _GSocket_Disable_Events(GSocket *socket)
{
socket->m_takesEvents = FALSE ;
}
/* _GSocket_Input_Timeout:
* For blocking sockets, wait until data is available or
* until timeout ellapses.
*/
GSocketError _GSocket_Input_Timeout(GSocket *socket)
{
if ( !socket->m_non_blocking )
{
UnsignedWide now , start ;
short formerTakesEvents = socket->m_takesEvents ;
Microseconds(&start);
now = start ;
socket->m_takesEvents = FALSE ;
while( (now.hi * 4294967296.0 + now.lo) - (start.hi * 4294967296.0 + start.lo) < socket->m_timeout * 1000.0 )
{
OTResult state ;
OTByteCount sz = 0 ;
state = OTGetEndpointState(socket->m_endpoint);
OTCountDataBytes( socket->m_endpoint , &sz ) ;
if ( state == T_INCON || sz > 0 )
{
socket->m_takesEvents = formerTakesEvents ;
return GSOCK_NOERROR;
}
Microseconds(&now);
}
socket->m_takesEvents = formerTakesEvents ;
socket->m_error = GSOCK_TIMEDOUT;
return GSOCK_TIMEDOUT;
}
return GSOCK_NOERROR;
}
/* _GSocket_Output_Timeout:
* For blocking sockets, wait until data can be sent without
* blocking or until timeout ellapses.
*/
GSocketError _GSocket_Output_Timeout(GSocket *socket)
{
if ( !socket->m_non_blocking )
{
UnsignedWide now , start ;
short formerTakesEvents = socket->m_takesEvents ;
Microseconds(&start);
now = start ;
socket->m_takesEvents = FALSE ;
while( (now.hi * 4294967296.0 + now.lo) - (start.hi * 4294967296.0 + start.lo) < socket->m_timeout * 1000.0 )
{
OTResult state ;
state = OTGetEndpointState(socket->m_endpoint);
if ( state == T_DATAXFER || state == T_INREL )
{
socket->m_takesEvents = formerTakesEvents ;
return GSOCK_NOERROR;
}
Microseconds(&now);
}
socket->m_takesEvents = formerTakesEvents ;
socket->m_error = GSOCK_TIMEDOUT;
return GSOCK_TIMEDOUT;
}
return GSOCK_NOERROR;
}
/* GSOCK_INPUT:
* There is data to be read in the input buffer. If, after a read
* operation, there is still data available, the callback function will
* be called again.
* GSOCK_OUTPUT:
* The socket is available for writing. That is, the next write call
* won't block. This event is generated only once, when the connection is
* first established, and then only if a call failed with GSOCK_WOULDBLOCK,
* when the output buffer empties again. This means that the app should
* assume that it can write since the first OUTPUT event, and no more
* OUTPUT events will be generated unless an error occurs.
* GSOCK_CONNECTION:
* Connection successfully established, for client sockets, or incoming
* client connection, for server sockets. Wait for this event (also watch
* out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call.
* GSOCK_LOST:
* The connection is lost (or a connection request failed); this could
* be due to a failure, or due to the peer closing it gracefully.
*/
void _GSocket_Internal_Proc(unsigned long e , void* d )
{
GSocket * socket = (GSocket*) d ;
OTEventCode ev = (OTEventCode) e ;
GSocketEvent event;
GSocketEvent event2;
GSocketCallback cback;
char *data;
GSocketCallback cback2;
char *data2;
if ( !socket )
return ;
event = GSOCK_MAX_EVENT ;
event2 = GSOCK_MAX_EVENT ;
cback = NULL;
data = NULL;
cback2 = NULL;
data2 = NULL;
/* Check that the socket still exists (it has not been
* destroyed) and for safety, check that the m_endpoint field
* is what we expect it to be.
*/
if ((socket != NULL) && (socket->m_takesEvents))
{
switch (ev)
{
case T_LISTEN :
event = GSOCK_CONNECTION ;
break ;
case T_CONNECT :
event = GSOCK_CONNECTION ;
event2 = GSOCK_OUTPUT ;
{
TCall retCall;
retCall.addr.buf = NULL;
retCall.addr.maxlen = 0;
retCall.opt.buf = NULL;
retCall.opt.maxlen = 0;
retCall.udata.buf = NULL;
retCall.udata.maxlen= 0;
OTRcvConnect( socket->m_endpoint , &retCall ) ;
}
break ;
case T_DISCONNECT :
event = GSOCK_LOST ;
break ;
case T_GODATA :
case T_GOEXDATA :
event = GSOCK_OUTPUT ;
break ;
case T_DATA :
event = GSOCK_INPUT ;
break ;
case T_EXDATA :
event = GSOCK_INPUT ;
break ;
}
if (event != GSOCK_MAX_EVENT)
{
cback = socket->m_cbacks[event];
data = socket->m_data[event];
if (event == GSOCK_LOST)
socket->m_detected = GSOCK_LOST_FLAG;
else
socket->m_detected |= (1 << event);
}
if (event2 != GSOCK_MAX_EVENT)
{
cback2 = socket->m_cbacks[event2];
data2 = socket->m_data[event2];
if (event2 == GSOCK_LOST)
socket->m_detected = GSOCK_LOST_FLAG;
else
socket->m_detected |= (1 << event2);
}
}
/* OK, we can now leave the critical section because we have
* already obtained the callback address (we make no further
* accesses to socket->whatever). However, the app should
* be prepared to handle events from a socket that has just
* been closed!
*/
if (cback != NULL)
(cback)(socket, event, data);
if (cback2 != NULL)
(cback2)(socket, event2, data2);
}
/* Hack added for Mac OS X */
GSocketError GAddress_UNIX_GetPath(GAddress *addr, char *path, size_t buf)
{
return GSOCK_INVADDR;
}
GSocketError GAddress_UNIX_SetPath(GAddress *addr, const char *path)
{
return GSOCK_INVADDR;
}
#endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -