📄 symbian_net.cpp
字号:
/* * GPAC - Multimedia Framework C SDK * * Copyright (c) Jean Le Feuvre 2000-2005 * All rights reserved * * This file is part of GPAC / common tools sub-project * * GPAC is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * GPAC is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */#if defined(WIN32) || defined(_WIN32_WCE)#ifdef _WIN32_WCE#include <winsock.h>#else#include <sys/timeb.h>#include <winsock2.h>#include <ws2tcpip.h>#endif#include <windows.h>#if !defined(__GNUC__)#if defined(IPV6_MULTICAST_IF)#define GPAC_IPV6 1#pragma message("Using WinSock IPV6")#else#undef GPAC_IPV6#pragma message("Using WinSock IPV4")#endif#endif/*common win32 redefs*/#define EAGAIN WSAEWOULDBLOCK#define EISCONN WSAEISCONN#define ENOTCONN WSAENOTCONN#define ECONNRESET WSAECONNRESET#define EMSGSIZE WSAEMSGSIZE#define ECONNABORTED WSAECONNABORTED#define ENETDOWN WSAENETDOWN#define LASTSOCKERROR WSAGetLastError()/*the number of sockets used. This because the WinSock lib needs init*/static int wsa_init = 0;#include <gpac/network.h>/*end-win32*/#else/*non-win32*/#include <unistd.h>#include <fcntl.h>#include <netdb.h> #ifndef __BEOS__#include <errno.h>#endif#ifndef __DARWIN__#include <sys/time.h>#endif#include <netinet/in.h>#include <netinet/tcp.h>#include <sys/socket.h>#include <arpa/inet.h>#include <gpac/network.h>#define INVALID_SOCKET -1#define SOCKET_ERROR -1#define LASTSOCKERROR errnotypedef s32 SOCKET;#define closesocket(v) close(v)#endif#ifdef __SYMBIAN32__#define SSO_CAST #else#define SSO_CAST (const char *)#endif#define SOCK_MICROSEC_WAIT 500#ifdef GPAC_IPV6static u32 ipv6_check_state = 0;#endif/*internal flags*/enum{ GF_SOCK_IS_TCP = 1<<9, GF_SOCK_IS_IPV6 = 1<<10, GF_SOCK_NON_BLOCKING = 1<<11, GF_SOCK_IS_MULTICAST = 1<<12, GF_SOCK_IS_LISTENING = 1<<13, GF_SOCK_HAS_SOURCE = 1<<14};struct __tag_socket{ u32 flags; SOCKET socket; /*destination address for sendto/recvfrom*/#ifdef GPAC_IPV6 struct sockaddr_storage dest_addr;#else struct sockaddr_in dest_addr;#endif u32 dest_addr_len;};/* Some NTP tools*/void gf_net_get_ntp(u32 *sec, u32 *frac){ struct timeval now;#ifdef WIN32 s32 gettimeofday(struct timeval *tp, void *tz);#endif gettimeofday(&now, NULL); *sec = (u32) (now.tv_sec) + GF_NTP_SEC_1900_TO_1970; *frac = (u32) ( (now.tv_usec << 12) + (now.tv_usec << 8) - ((now.tv_usec * 3650) >> 6) );}u32 gf_net_has_ipv6(){#ifdef GPAC_IPV6 if (!ipv6_check_state) { SOCKET s;#ifdef WIN32 if (!wsa_init) { WSADATA Data; if (WSAStartup(0x0202, &Data)!=0) { ipv6_check_state = 1; return 0; } }#endif s = socket(PF_INET6, SOCK_STREAM, 0); if (!s) ipv6_check_state = 1; else { ipv6_check_state = 2; closesocket(s); }#ifdef WIN32 if (!wsa_init) WSACleanup();#endif } return (ipv6_check_state==2);#else return 0;#endif}#ifdef GPAC_IPV6static struct addrinfo *gf_sk_get_ipv6_addr(char *PeerName, u16 PortNumber, int family, int flags, int sock_type){ struct addrinfo *res=NULL; struct addrinfo hints; char node[50], portstring[20], *service, *dest; service = dest = NULL; memset(&hints, 0, sizeof(hints)); hints.ai_socktype = sock_type; hints.ai_family = family; hints.ai_flags = flags; if (PortNumber) { sprintf (portstring, "%d", PortNumber); service = (char *)portstring; } if (PeerName) { strcpy(node, PeerName); if (node[0]=='[') { node[strlen(node)-1] = 0; strcpy(node, &node[1]); } dest = (char *) node; } if (getaddrinfo((const char *)dest, (const char *)service, &hints, &res) != 0) return NULL; return res;}static Bool gf_sk_ipv6_set_remote_address(GF_Socket *sock, char *address, u16 PortNumber){ struct addrinfo *res = gf_sk_get_ipv6_addr(address, PortNumber, AF_UNSPEC, 0, (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM); if (!res) return 0; memcpy(&sock->dest_addr, res->ai_addr, res->ai_addrlen); sock->dest_addr_len = res->ai_addrlen; freeaddrinfo(res); return 1;}#endifGF_Err gf_sk_get_host_name(char *buffer){ s32 ret = gethostname(buffer, GF_MAX_IP_NAME_LEN); return (ret == SOCKET_ERROR) ? GF_IP_ADDRESS_NOT_FOUND : GF_OK;}GF_Err gf_sk_get_local_ip(GF_Socket *sock, char *buffer){#ifdef GPAC_IPV6 char clienthost[NI_MAXHOST]; struct sockaddr_storage clientaddr; socklen_t addrlen = sizeof(clientaddr); if (getsockname(sock->socket, (struct sockaddr *)&clientaddr, &addrlen)) return GF_IP_NETWORK_FAILURE; if (getnameinfo((struct sockaddr *)&clientaddr, addrlen, clienthost, sizeof(clienthost), NULL, 0, NI_NUMERICHOST)) return GF_IP_NETWORK_FAILURE; strcpy(buffer, clienthost);#else char *ip; struct sockaddr_in name; u32 len = sizeof(struct sockaddr_in); if (getsockname(sock->socket, (struct sockaddr*) &name, &len)) return GF_IP_NETWORK_FAILURE; ip = inet_ntoa(name.sin_addr); if (!ip) return GF_IP_NETWORK_FAILURE; strcpy(buffer, ip);#endif return GF_OK;}GF_Socket *gf_sk_new(u32 SocketType){ GF_Socket *tmp; /*init WinSock*/#ifdef WIN32 WSADATA Data; if (!wsa_init && (WSAStartup(0x0202, &Data)!=0) ) return NULL;#endif if ((SocketType != GF_SOCK_TYPE_UDP) && (SocketType != GF_SOCK_TYPE_TCP)) return NULL; GF_SAFEALLOC(tmp, GF_Socket); if (!tmp) return NULL; if (SocketType == GF_SOCK_TYPE_TCP) tmp->flags |= GF_SOCK_IS_TCP;#ifdef GPAC_IPV6 memset(&tmp->dest_addr, 0, sizeof(struct sockaddr_storage));#else memset(&tmp->dest_addr, 0, sizeof(struct sockaddr_in)); tmp->dest_addr_len = sizeof(struct sockaddr);#endif#ifdef WIN32 wsa_init ++;#endif return tmp;}GF_Err gf_sk_set_buffer_size(GF_Socket *sock, Bool SendBuffer, u32 NewSize){ if (!sock || !sock->socket) return GF_BAD_PARAM; if (SendBuffer) { setsockopt(sock->socket, SOL_SOCKET, SO_SNDBUF, (char *) &NewSize, sizeof(u32) ); } else { setsockopt(sock->socket, SOL_SOCKET, SO_RCVBUF, (char *) &NewSize, sizeof(u32) ); } return GF_OK;}GF_Err gf_sk_set_block_mode(GF_Socket *sock, u32 NonBlockingOn){#ifdef WIN32 s32 res; u_long val = NonBlockingOn; res = ioctlsocket(sock->socket, FIONBIO, &val); if (res) return GF_SERVICE_ERROR;#else// s32 flag = fcntl(sock->socket, F_GETFL, 0);// res = fcntl(sock->socket, F_SETFL, flag | O_NONBLOCK);// if (res) return GF_SERVICE_ERROR;#endif if (NonBlockingOn) { sock->flags |= GF_SOCK_NON_BLOCKING; } else { sock->flags &= ~GF_SOCK_NON_BLOCKING; } return GF_OK;}static void gf_sk_free(GF_Socket *sock){ /*leave multicast*/ if (sock->socket && (sock->flags & GF_SOCK_IS_MULTICAST) ) { struct ip_mreq mreq;#ifdef GPAC_IPV6 struct sockaddr *addr = (struct sockaddr *)&sock->dest_addr; if (addr->sa_family==AF_INET6) { struct ipv6_mreq mreq6; memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr)); mreq6.ipv6mr_interface= 0; setsockopt(sock->socket, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char *) &mreq6, sizeof(mreq6)); } else { mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr; mreq.imr_interface.s_addr = INADDR_ANY; setsockopt(sock->socket, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *) &mreq, sizeof(mreq)); }#else mreq.imr_multiaddr.s_addr = sock->dest_addr.sin_addr.s_addr; mreq.imr_interface.s_addr = INADDR_ANY; setsockopt(sock->socket, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *) &mreq, sizeof(mreq));#endif } if (sock->socket) closesocket(sock->socket); sock->socket = (SOCKET) 0L;}void gf_sk_del(GF_Socket *sock){ gf_sk_free(sock);#ifdef WIN32 wsa_init --; if (!wsa_init) WSACleanup();#endif free(sock);}void gf_sk_reset(GF_Socket *sock){ u32 clear; if (sock) setsockopt(sock->socket, SOL_SOCKET, SO_ERROR, (char *) &clear, sizeof(u32) );}s32 gf_sk_get_handle(GF_Socket *sock) { return sock->socket;}//connects a socket to a remote peer on a given portGF_Err gf_sk_connect(GF_Socket *sock, char *PeerName, u16 PortNumber){ s32 ret;#ifdef GPAC_IPV6 u32 type = (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM; struct addrinfo *res, *aip; gf_sk_free(sock); res = gf_sk_get_ipv6_addr(PeerName, PortNumber, AF_UNSPEC, AI_PASSIVE, type); if (!res) return GF_IP_CONNECTION_FAILURE; /*for all interfaces*/ for (aip=res; aip!=NULL; aip=aip->ai_next) { if (type != (u32) aip->ai_socktype) continue; sock->socket = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol); if (sock->socket == INVALID_SOCKET) { sock->socket = (SOCKET)NULL; continue; } if (sock->flags & GF_SOCK_NON_BLOCKING) gf_sk_set_block_mode(sock, 1); if (aip->ai_family==PF_INET6) sock->flags |= GF_SOCK_IS_IPV6; else sock->flags &= ~GF_SOCK_IS_IPV6; ret = connect(sock->socket, aip->ai_addr, aip->ai_addrlen); if (ret == SOCKET_ERROR) { closesocket(sock->socket); sock->socket = (SOCKET)NULL; continue; } memcpy(&sock->dest_addr, aip->ai_addr, aip->ai_addrlen); sock->dest_addr_len = aip->ai_addrlen; freeaddrinfo(res); return GF_OK; } freeaddrinfo(res); return GF_IP_CONNECTION_FAILURE;#else struct hostent *Host; if (!sock->socket) sock->socket = socket(AF_INET, (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM, 0); /*setup the address*/ sock->dest_addr.sin_family = AF_INET; sock->dest_addr.sin_port = htons(PortNumber); /*get the server IP*/ sock->dest_addr.sin_addr.s_addr = inet_addr(PeerName); if (sock->dest_addr.sin_addr.s_addr==INADDR_NONE) { Host = gethostbyname(PeerName); if (Host == NULL) { switch (LASTSOCKERROR) {#ifndef __SYMBIAN32__ case ENETDOWN: return GF_IP_NETWORK_FAILURE; //case ENOHOST: return GF_IP_ADDRESS_NOT_FOUND;#endif default: return GF_IP_NETWORK_FAILURE; } } memcpy((char *) &sock->dest_addr.sin_addr, Host->h_addr_list[0], sizeof(u32)); } if (sock->flags & GF_SOCK_IS_TCP) { ret = connect(sock->socket, (struct sockaddr *) &sock->dest_addr, sizeof(struct sockaddr)); if (ret == SOCKET_ERROR) { switch (LASTSOCKERROR) { case EAGAIN: return GF_IP_SOCK_WOULD_BLOCK; case EISCONN: return GF_OK; default: return GF_IP_CONNECTION_FAILURE; } } }#endif return GF_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -