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

📄 os_net.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
	return GF_OK;}//binds the given socket to the specified port. If ReUse is true//this will enable reuse of ports on a single machineGF_Err gf_sk_bind(GF_Socket *sock, u16 port, char *peer_name, u16 peer_port, u32 options){#ifdef GPAC_IPV6	struct addrinfo *res, *aip;	int af;	u32 type;#else	size_t addrlen;	struct sockaddr_in LocalAdd;	struct hostent *Host;	char buf[GF_MAX_IP_NAME_LEN];#endif	s32 ret;	s32 optval;	if (!sock || sock->socket) return GF_BAD_PARAM;#ifdef GPAC_IPV6	type = (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM;	af = (options & GF_SOCK_FORCE_IPV6) ? PF_INET6 : PF_UNSPEC;	if (!gf_net_has_ipv6()) af = PF_INET;	/*probe way to peer: is it V4 or V6? */	if (peer_name && peer_port) {		res = gf_sk_get_ipv6_addr(peer_name, peer_port, af, AI_PASSIVE, type);		if (!res) return GF_IP_CONNECTION_FAILURE;#ifdef WIN32		/*win32 has troubles redirecting IPV4 datagrams to IPV6 sockets, so override 		local family type to avoid IPV4(S)->IPV6(C) UDP*/		af = res->ai_family;#endif		memcpy(&sock->dest_addr, res->ai_addr, res->ai_addrlen);		sock->dest_addr_len = res->ai_addrlen;		freeaddrinfo(res);	}		res = gf_sk_get_ipv6_addr(NULL, port, af, 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;		if (aip->ai_next && (aip->ai_next->ai_family==PF_INET) && !gf_net_is_ipv6(peer_name)) continue;		sock->socket = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol);		if (sock->socket == INVALID_SOCKET) {			sock->socket = (SOCKET)NULL;			continue;		}		if (options & GF_SOCK_REUSE_PORT) {			optval = 1;			setsockopt(sock->socket, SOL_SOCKET, SO_REUSEADDR, (const char *) &optval, sizeof(optval));#ifdef SO_REUSEPORT			optval = 1;			setsockopt(sock->socket, SOL_SOCKET, SO_REUSEPORT, SSO_CAST &optval, sizeof(optval));#endif		}		if (sock->flags & GF_SOCK_NON_BLOCKING) gf_sk_set_block_mode(sock, 1);		ret = bind(sock->socket, aip->ai_addr, aip->ai_addrlen);		if (ret == SOCKET_ERROR) {			closesocket(sock->socket);			sock->socket = (SOCKET)NULL;			continue;		}		if (aip->ai_family==PF_INET6) sock->flags |= GF_SOCK_IS_IPV6;		else sock->flags &= ~GF_SOCK_IS_IPV6;		if (peer_name && peer_port) 			sock->flags |= GF_SOCK_HAS_PEER;		freeaddrinfo(res);		return GF_OK;	}	freeaddrinfo(res);	return GF_IP_CONNECTION_FAILURE;#else	sock->socket = socket(AF_INET, (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM, 0);	if (sock->flags & GF_SOCK_NON_BLOCKING) gf_sk_set_block_mode(sock, 1);	sock->flags &= ~GF_SOCK_IS_IPV6;	memset((void *) &LocalAdd, 0, sizeof(LocalAdd));	ret = gethostname(buf, GF_MAX_IP_NAME_LEN);	if (ret == SOCKET_ERROR) {		GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[socket] cannot get localhost name - socket error %x\n", LASTSOCKERROR));		return GF_IP_ADDRESS_NOT_FOUND;	}	/*get the IP address*/	Host = gethostbyname(buf);	if (Host == NULL) {		GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[socket] cannot resolve localhost name - socket error %x\n", LASTSOCKERROR));		return GF_IP_ADDRESS_NOT_FOUND;	}	/*setup the address*/	memcpy((char *) &LocalAdd.sin_addr, Host->h_addr_list[0], sizeof(LocalAdd.sin_addr));	LocalAdd.sin_family = AF_INET;	LocalAdd.sin_addr.s_addr = INADDR_ANY;	LocalAdd.sin_port = htons(port);	addrlen = sizeof(struct sockaddr_in);	if (options & GF_SOCK_REUSE_PORT) {		optval = 1;		setsockopt(sock->socket, SOL_SOCKET, SO_REUSEADDR, SSO_CAST &optval, sizeof(optval));#ifdef SO_REUSEPORT		optval = 1;		setsockopt(sock->socket, SOL_SOCKET, SO_REUSEPORT, SSO_CAST &optval, sizeof(optval));#endif	}	/*bind the socket*/	ret = bind(sock->socket, (struct sockaddr *) &LocalAdd, addrlen);	if (ret == SOCKET_ERROR) {		GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[socket] cannot bind socket - socket error %x\n", LASTSOCKERROR));		return GF_IP_CONNECTION_FAILURE;	}	if (peer_name && peer_port) {		sock->dest_addr.sin_port = htons(peer_port);		sock->dest_addr.sin_family = AF_INET;		sock->dest_addr.sin_addr.s_addr = inet_addr(peer_name);		if (sock->dest_addr.sin_addr.s_addr == INADDR_NONE) {			Host = gethostbyname(peer_name);			if (Host == NULL) return GF_IP_ADDRESS_NOT_FOUND;			memcpy((char *) &sock->dest_addr.sin_addr, Host->h_addr_list[0], sizeof(u32));		}		sock->flags |= GF_SOCK_HAS_PEER;	}#endif	if (sock->flags & GF_SOCK_HAS_PEER) {		GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[socket] socket bound to port %d - remote peer: %s:%d\n", port, peer_name, peer_port));	} else {		GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[socket] socket bound to port %d\n", port));	}	return GF_OK;}//send length bytes of a bufferGF_Err gf_sk_send(GF_Socket *sock, char *buffer, u32 length){	GF_Err e;	u32 Count, Res;#ifndef __SYMBIAN32__	u32 ready;	struct timeval timeout;	fd_set Group;#endif	e = GF_OK;	//the socket must be bound or connected	if (!sock || !sock->socket) return GF_BAD_PARAM;#ifndef __SYMBIAN32__	//can we write?	FD_ZERO(&Group);	FD_SET(sock->socket, &Group);	timeout.tv_sec = 0;	timeout.tv_usec = SOCK_MICROSEC_WAIT;	ready = select(sock->socket+1, NULL, &Group, NULL, &timeout);	if (ready == SOCKET_ERROR) {		switch (LASTSOCKERROR) {		case EAGAIN:			return GF_IP_SOCK_WOULD_BLOCK;		default:			return GF_IP_NETWORK_FAILURE;		}	}	//should never happen (to check: is writeability is guaranteed for not-connected sockets)	if (!ready || !FD_ISSET(sock->socket, &Group)) {		return GF_IP_NETWORK_EMPTY;	}#endif	//direct writing	Count = 0;	while (Count < length) {		if (sock->flags & GF_SOCK_HAS_PEER) {			Res = sendto(sock->socket, (char *) &buffer[Count], length - Count, 0, (struct sockaddr *) &sock->dest_addr, sock->dest_addr_len);		} else {			Res = send(sock->socket, (char *) &buffer[Count], length - Count, 0);		}		if (Res == SOCKET_ERROR) {			switch (Res = LASTSOCKERROR) {			case EAGAIN:				return GF_IP_SOCK_WOULD_BLOCK;#ifndef __SYMBIAN32__			case ENOTCONN:			case ECONNRESET:				return GF_IP_CONNECTION_CLOSED;#endif			default:				return GF_IP_NETWORK_FAILURE;			}		}		Count += Res;	}	return GF_OK;}u32 gf_sk_is_multicast_address(char *multi_IPAdd){#ifdef GPAC_IPV6	u32 val; 	char *sep;	struct addrinfo *res;	if (!multi_IPAdd) return 0;	/*IPV6 multicast address*/	sep = strchr(multi_IPAdd, ':');	if (sep) sep = strchr(multi_IPAdd, ':');	if (sep && !strnicmp(multi_IPAdd, "ff", 2)) return 1;	/*ipv4 multicast address*/	res = gf_sk_get_ipv6_addr(multi_IPAdd, 7000, AF_UNSPEC, AI_PASSIVE, SOCK_DGRAM);	if (!res) return 0;	val = 0;	if (res->ai_addr->sa_family == AF_INET) {	        val = IN_MULTICAST(ntohl(((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr));  	} else if (res->ai_addr->sa_family == AF_INET6) {		val = IN6_IS_ADDR_MULTICAST(& ((struct sockaddr_in6 *)res->ai_addr)->sin6_addr);	}	freeaddrinfo(res);	return val;#else	if (!multi_IPAdd) return 0;	return ((htonl(inet_addr(multi_IPAdd)) >> 8) & 0x00f00000) == 0x00e00000;	#endif}GF_Err gf_sk_setup_multicast(GF_Socket *sock, char *multi_IPAdd, u16 MultiPortNumber, u32 TTL, Bool NoBind, char *local_interface_ip){	s32 ret;	u32 flag; 	struct ip_mreq M_req;	u32 optval;#ifdef GPAC_IPV6	struct sockaddr *addr;	struct addrinfo *res, *aip;	u32 type;#else	u_long local_add_id;#endif	if (!sock || sock->socket) return GF_BAD_PARAM;	if (TTL > 255) TTL = 255;		/*check the address*/	if (!gf_sk_is_multicast_address(multi_IPAdd)) return GF_BAD_PARAM;#ifdef GPAC_IPV6	type = (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM;	res = gf_sk_get_ipv6_addr(local_interface_ip, MultiPortNumber, AF_UNSPEC, AI_PASSIVE, type);	if (!res) {		if (local_interface_ip) {			res = gf_sk_get_ipv6_addr(NULL, MultiPortNumber, AF_UNSPEC, AI_PASSIVE, type);			local_interface_ip = NULL;		}		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 (aip->ai_next && (aip->ai_next->ai_family==PF_INET) && !gf_net_is_ipv6(multi_IPAdd)) continue;		/*enable address reuse*/		optval = 1;		setsockopt(sock->socket, SOL_SOCKET, SO_REUSEADDR, (const char *) &optval, sizeof(optval));#ifdef SO_REUSEPORT		optval = 1;		setsockopt(sock->socket, SOL_SOCKET, SO_REUSEPORT, SSO_CAST &optval, sizeof(optval));#endif		/*TODO: copy over other properties (recption buffer size & co)*/		if (sock->flags & GF_SOCK_NON_BLOCKING) gf_sk_set_block_mode(sock, 1);	    memcpy(&sock->dest_addr, aip->ai_addr, aip->ai_addrlen);		sock->dest_addr_len = aip->ai_addrlen;		if (!NoBind) {			ret = bind(sock->socket, aip->ai_addr, aip->ai_addrlen);			if (ret == SOCKET_ERROR) {				closesocket(sock->socket);				sock->socket = (SOCKET)NULL;				continue;			}		}		if (aip->ai_family==PF_INET6) sock->flags |= GF_SOCK_IS_IPV6;		else sock->flags &= ~GF_SOCK_IS_IPV6;		break;	}	freeaddrinfo(res);	if (!sock->socket) return GF_IP_CONNECTION_FAILURE;		if (!gf_sk_ipv6_set_remote_address(sock, multi_IPAdd, MultiPortNumber)) 		return GF_IP_CONNECTION_FAILURE;	addr = (struct sockaddr *)&sock->dest_addr;	if (addr->sa_family == AF_INET) {        M_req.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;        M_req.imr_interface.s_addr = INADDR_ANY;		ret = setsockopt(sock->socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &M_req, sizeof(M_req));		if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE;		/*set TTL*/		ret = setsockopt(sock->socket, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &TTL, sizeof(TTL));		if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE;		/*Disable loopback*/		flag = 1;		ret = setsockopt(sock->socket, IPPROTO_IP, IP_MULTICAST_LOOP, (char *) &flag, sizeof(flag));		if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE;	}	if (addr->sa_family == AF_INET6) {		struct ipv6_mreq M_reqV6;        				memcpy(&M_reqV6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr));        M_reqV6.ipv6mr_interface = 0;		/*set TTL*/		ret = setsockopt(sock->socket, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *) &TTL, sizeof(TTL));		if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE;		/*Disable loopback*/		flag = 1;		ret = setsockopt(sock->socket, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (char *) &flag, sizeof(flag));		if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE;        		ret = setsockopt(sock->socket, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char *) &M_reqV6, sizeof(M_reqV6));		if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE;	} #else	sock->socket = socket(AF_INET, (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM, 0);	if (sock->flags & GF_SOCK_NON_BLOCKING) gf_sk_set_block_mode(sock, 1);	sock->flags &= ~GF_SOCK_IS_IPV6;	/*enable address reuse*/	optval = 1;	ret = setsockopt(sock->socket, SOL_SOCKET, SO_REUSEADDR, SSO_CAST &optval, sizeof(optval));#ifdef SO_REUSEPORT	optval = 1;	setsockopt(sock->socket, SOL_SOCKET, SO_REUSEPORT, SSO_CAST &optval, sizeof(optval));#endif	if (local_interface_ip) local_add_id = inet_addr(local_interface_ip);	else local_add_id = htonl(INADDR_ANY);	if (!NoBind) {		struct sockaddr_in local_address;		local_address.sin_family = AF_INET;		local_address.sin_addr.s_addr = local_add_id;		local_address.sin_port = htons( MultiPortNumber);		ret = bind(sock->socket, (struct sockaddr *) &local_address, sizeof(local_address));		if (ret == SOCKET_ERROR) {			/*retry without specifying the local add*/			local_address.sin_addr.s_addr = local_add_id = htonl(INADDR_ANY);			local_interface_ip = NULL;			ret = bind(sock->socket, (struct sockaddr *) &local_address, sizeof(local_address));			if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE;		}		/*setup local interface*/		if (local_interface_ip) {			ret = setsockopt(sock->socket, IPPROTO_IP, IP_MULTICAST_IF, (char *) &local_add_id, sizeof(local_add_id));			if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE;		}	}	/*now join the multicast*/	M_req.imr_multiaddr.s_addr = inet_addr(multi_IPAdd);	M_req.imr_interface.s_addr = local_add_id;	ret = setsockopt(sock->socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &M_req, sizeof(M_req));	if (ret == SOCKET_ERROR) {		GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[core] cannot join multicast: error %d\n", LASTSOCKERROR));		return GF_IP_CONNECTION_FAILURE;	}	/*set the Time To Live*/	ret = setsockopt(sock->socket, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&TTL, sizeof(TTL));	if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE;	/*Disable loopback*/	flag = 1;	ret = setsockopt(sock->socket, IPPROTO_IP, IP_MULTICAST_LOOP, (char *) &flag, sizeof(flag));	if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE;	sock->dest_addr.sin_family = AF_INET;	sock->dest_addr.sin_addr.s_addr = M_req.imr_multiaddr.s_addr;	sock->dest_addr.sin_port = htons( MultiPortNumber);#endif	sock->flags |= GF_SOCK_IS_MULTICAST | GF_SOCK_HAS_PEER;	return GF_OK;}//fetch nb bytes on a socket and fill the buffer from startFrom//length is the allocated size of the receiving buffer//BytesRead is the number of bytes read from the networkGF_Err gf_sk_receive(GF_Socket *sock, char *buffer, u32 length, u32 startFrom, u32 *BytesRead){	GF_Err e;	u32 res;#ifndef __SYMBIAN32__	u32 ready;	struct timeval timeout;	fd_set Group;#endif	e = GF_OK;	*BytesRead = 0;	if (!sock->socket) {		assert(0);		return GF_BAD_PARAM;	}	if (startFrom >= length) {		assert(0);		return GF_IO_ERR;	}#ifndef __SYMBIAN32__	//can we read?	FD_ZERO(&Group);	FD_SET(sock->socket, &Group);	timeout.tv_sec = 0;	timeout.tv_usec = SOCK_MICROSEC_WAIT;	res = 0;	ready = select(sock->socket+1, &Group, NULL, NULL, &timeout);	if (ready == SOCKET_ERROR) {		switch (LASTSOCKERROR) {		case EAGAIN:			return GF_IP_SOCK_WOULD_BLOCK;		default:			GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[socket] cannot select (error %d)\n", LASTSOCKERROR));			return GF_IP_NETWORK_FAILURE;		}	}	if (!FD_ISSET(sock->socket, &Group)) {		GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[socket] nothing to be read\n"));		return GF_IP_NETWORK_EMPTY;	}#endif	if (sock->flags & GF_SOCK_HAS_PEER)		res = recvfrom(sock->socket, (char *) buffer + startFrom, length - startFrom, 0, (struct sockaddr *)&sock->dest_addr, &sock->dest_addr_len);	else		res = recv(sock->socket, (char *) buffer + startFrom, length - startFrom, 0);

⌨️ 快捷键说明

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