⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_net.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *			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 0 && 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,	/*socket is bound to a specific dest (server) or source (client) */	GF_SOCK_HAS_PEER = 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}GF_EXPORTBool gf_net_is_ipv6(char *address){	char *sep;	if (!address) return 0;	sep = strchr(address, ':');	if (sep) sep = strchr(address, ':');	return sep ? 1 : 0;}#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;#ifdef WIN32		if (!wsa_init) {			WSADATA Data;			if (WSAStartup(0x0202, &Data)!=0) return NULL;			wsa_init = 1;		}#endif	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];	if (sock->flags & GF_SOCK_HAS_PEER) {		if (getnameinfo((struct sockaddr *)&sock->dest_addr, sock->dest_addr_len, clienthost, sizeof(clienthost), NULL, 0, NI_NUMERICHOST)) 			return GF_IP_NETWORK_FAILURE;	} else {		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;	if (sock->flags & GF_SOCK_HAS_PEER) {		ip = inet_ntoa(sock->dest_addr.sin_addr);	} else {		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){	s32 res;#ifdef WIN32	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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -