📄 gsocket.cpp
字号:
return -1; /* Translate a system address into a GSocket address */ if (!m_peer) { m_peer = GAddress_new(); if (!m_peer) { m_error = GSOCK_MEMERR; return -1; } } err = _GAddress_translate_from(m_peer, &from, fromlen); if (err != GSOCK_NOERROR) { GAddress_destroy(m_peer); m_peer = NULL; m_error = err; return -1; }#endif return ret;}int GSocket::Send_Stream(const char *buffer, int size){ OTFlags flags = 0 ; OTResult res ; res = OTSnd( m_endpoint , (void*) buffer , size , flags ) ; return res ;}int GSocket::Send_Dgram(const char *buffer, int size){ int ret = -1 ;// TODO#if 0 struct sockaddr *addr; int len ; GSocketError err; if (!m_peer) { m_error = GSOCK_INVADDR; return -1; } err = _GAddress_translate_to(m_peer, &addr, &len); if (err != GSOCK_NOERROR) { m_error = err; return -1; } ret = sendto(m_endpoint, buffer, size, 0, addr, len); /* Frees memory allocated from _GAddress_translate_to */ free(addr);#endif return ret;}/* Compatibility functions for GSocket */GSocket *GSocket_new(void){ GSocket *newsocket = new GSocket(); if(newsocket->IsOk()) return newsocket; delete newsocket; return NULL;}/* * ------------------------------------------------------------------------- * 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() ) 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() ) 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 = htonl(hostaddr) ; return GSOCK_NOERROR;}struct service_entry{ const char * name ; unsigned short port ; const 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() ) 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 ntohl(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(){ if ( m_takesEvents ) return ; { OTResult state ; m_takesEvents = true ; state = OTGetEndpointState(m_endpoint); { OTByteCount sz = 0 ; OTCountDataBytes( m_endpoint , &sz ) ; if ( state == T_INCON || sz > 0 ) { m_detected |= GSOCK_INPUT_FLAG ; (m_cbacks[GSOCK_INPUT])(this, GSOCK_INPUT, m_data[GSOCK_INPUT]); } } { if ( state == T_DATAXFER || state == T_INREL ) { m_detected |=GSOCK_OUTPUT_FLAG ; (m_cbacks[GSOCK_OUTPUT])(this, GSOCK_OUTPUT, m_data[GSOCK_OUTPUT]); } } }}void GSocket::Disable_Events(){ m_takesEvents = false ;}/* _GSocket_Input_Timeout: * For blocking sockets, wait until data is available or * until timeout ellapses. */GSocketError GSocket::Input_Timeout(){ if ( !m_non_blocking ) { UnsignedWide now , start ; bool formerTakesEvents = m_takesEvents ; Microseconds(&start); now = start ; m_takesEvents = false ; while( (now.hi * 4294967296.0 + now.lo) - (start.hi * 4294967296.0 + start.lo) < m_timeout * 1000.0 ) { OTResult state ; OTByteCount sz = 0 ; state = OTGetEndpointState(m_endpoint); OTCountDataBytes( m_endpoint , &sz ) ; if ( state == T_INCON || sz > 0 ) { m_takesEvents = formerTakesEvents ; return GSOCK_NOERROR; } Microseconds(&now); } m_takesEvents = formerTakesEvents ; 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(){ if ( !m_non_blocking ) { UnsignedWide now , start ; bool formerTakesEvents = m_takesEvents ; Microseconds(&start); now = start ; m_takesEvents = false ; while( (now.hi * 4294967296.0 + now.lo) - (start.hi * 4294967296.0 + start.lo) < m_timeout * 1000.0 ) { OTResult state ; state = OTGetEndpointState(m_endpoint); if ( state == T_DATAXFER || state == T_INREL ) { m_takesEvents = formerTakesEvents ; return GSOCK_NOERROR; } Microseconds(&now); } m_takesEvents = formerTakesEvents ; 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 ; if ( !socket ) return ; OTEventCode ev = (OTEventCode) e ; GSocketEvent event; GSocketEvent event2; GSocketCallback cback; char *data; GSocketCallback cback2; char *data2; 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 + -