wow-socket文件说明

wow-socket文件说明

  • 项目地址:https://gitee.com/wow-iot/wow-iot7
  • 本文件的的功能主要用于socket操作,主要涉及打开、关闭、连接(支持IP与域名方式)、监听、接收、发送消息、接收消息、获取/设置参数、获取本地/对象信息;

打开与关闭

int wow_socket_open(SocketType_E eType)
{
	switch(eType){
		case SOCKET_TYPE_TCP:
			return socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
		case SOCKET_TYPE_UDP:
			return socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
		default:
			break;
	}
	
	return PARAM_INPUT_ARG_INVALID;
}

void wow_socket_close(int nSktfd)
{
	CHECK_RET_VOID(nSktfd >= 0);

	shutdown(nSktfd,SHUT_RDWR);
	close(nSktfd);
}

连接(支持IP与域名方式)

int wow_socket_connect(int nSktfd,const char *pcAddr, uint16_t u16Port,uint32_t u32TimeoutMs)
{
	CHECK_RET_VAL_P(nSktfd >= 0 ,-PARAM_INPUT_ARG_INVALID,"param input arg invalid!\n");
	(void)u32TimeoutMs;
	int ret = -1;

	
	struct sockaddr_in saddr;
	bzero(&saddr, sizeof(saddr));
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(u16Port);

	if(pcAddr && _host_is_ip(pcAddr) == 0){
		inet_pton(AF_INET,pcAddr, &saddr.sin_addr); 
		
		struct hostent *he;
		he = gethostbyname(pcAddr);///<耗时 尽可能不使用
		CHECK_RET_VAL(he,-1);
		memcpy(&saddr.sin_addr, he->h_addr, sizeof(struct in_addr));
	}else{
		saddr.sin_addr.s_addr = pcAddr? inet_addr(pcAddr):INADDR_ANY;
	}
	
	ret = connect(nSktfd, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
	if((ret == 0) ||  (ret < 0 && errno == EISCONN)){//EISCONN 已建立连接
		return 0;
	} 
	else if (ret < 0 && errno == EINPROGRESS){//非阻塞模式下
		//判断链接是否成功
		fd_set wset;
		struct timeval tv;
		tv.tv_sec  = u32TimeoutMs *1000;
		tv.tv_usec = u32TimeoutMs%1000 *1000;
		FD_ZERO(&wset);
		FD_SET(nSktfd, &wset);

		ret = select(nSktfd+1, NULL, &wset, NULL,&tv);
		CHECK_RET_VAL_P_A(ret > 0 ,-SYSTEM_SELECT_FAILED, "select false!\n");
		if(FD_ISSET(nSktfd, &wset)){
			int err = -1;
			socklen_t len = sizeof(int);
			ret = getsockopt(nSktfd,  SOL_SOCKET, SO_ERROR ,&err, &len);
			CHECK_RET_VAL_P_A(ret == 0 ,-SOCKET_GET_OPT_FAILED, "select sockfd not set");
		}
		return 0;
	}
	
	return -WOW_FAILED;
}

绑定(默认本机任意地址)

	int wow_socket_bind(int nSktfd,const char *pcAddr, uint16_t u16Port)
	{
		CHECK_RET_VAL_P(nSktfd >= 0 ,-PARAM_INPUT_ARG_INVALID,"param input arg invalid!\n");

		int  ret = 0;
		
	///<端口地址释放后立即生效 支持端口重载
	///<端口复用最常用的用途应该是防止服务器重启时之前绑定的端口还未释放或者程序突然退出而系统没有释放端口
	#ifdef SO_REUSEADDR
		int reuseaddr = 1;
		ret = setsockopt(nSktfd, SOL_SOCKET, SO_REUSEADDR, (int *)&reuseaddr, sizeof(reuseaddr));
		CHECK_RET_VAL_P_A(ret == 0,-SOCKET_SET_OPT_FAILED,"reuse addr failed!\n");
	#endif

	#ifdef SO_REUSEPORT
		int reuseport = 1;
		ret = setsockopt(nSktfd, SOL_SOCKET, SO_REUSEPORT, (int *)&reuseport, sizeof(reuseport));
		CHECK_RET_VAL_P_A(ret == 0,-SOCKET_SET_OPT_FAILED,"reuse port failed!\n");
	#endif

		struct sockaddr_in saddr;
		/*为TCP链接设置IP和端口等信息*/
		bzero(&saddr, sizeof(saddr));
		saddr.sin_family = AF_INET;
		saddr.sin_addr.s_addr = pcAddr? inet_addr(pcAddr):INADDR_ANY;
		saddr.sin_port = htons(u16Port);

		/*地址与socket绑定bind*/
		return bind(nSktfd, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
		
	}

监听

int wow_socket_listen(int nSktfd, size_t snMaxc)
{
	CHECK_RET_VAL_P(nSktfd >= 0 ,-PARAM_INPUT_ARG_INVALID,"param input arg invalid!\n");

	if(snMaxc == 0){
		char *ptr;
		if((ptr = getenv("LISTENQ")) != NULL){
			snMaxc = atoi(ptr);
		}else{
			snMaxc = 1024;
		}

	}
	return listen(nSktfd, snMaxc);
	
}

等待接收

int wow_socket_accept(int nSktfd,char *pcAddr, uint16_t* u16Port)
{
	CHECK_RET_VAL_P(nSktfd >= 0 ,-PARAM_INPUT_ARG_INVALID,"param input arg invalid!\n");

	struct sockaddr_in saddr = {0};
	socklen_t len = sizeof(struct sockaddr_in);

	int fd = accept(nSktfd, (struct sockaddr *)&saddr, &len);
	CHECK_RET_VAL(fd > 0,-SOCKET_ACCEPT_FAILED);
	
///<减少反应延迟
#ifdef TCP_NODELAY	
	int enable = 1;
	setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&enable, sizeof(enable));
#endif

	if(pcAddr){
		strcpy(pcAddr,inet_ntoa(saddr.sin_addr)); 
	}
	if(u16Port){
		*u16Port = ntohs(saddr.sin_port);
	} 

	return fd;
}

接收信息

int wow_socket_trecv(int nSktfd, uint8_t* pu8Data, size_t snSize)
{
	CHECK_RET_VAL_P(nSktfd >= 0 && snSize > 0,-PARAM_INPUT_ARG_INVALID,"param input arg invalid!\n");
	CHECK_RET_VAL_P(pu8Data , -PARAM_INPUT_DATA_IS_NULL ,"param input data invalid!\n");

	//read(nSktfd,pu8Data,snSize);
	int real = recv(nSktfd, pu8Data, snSize, MSG_DONTWAIT);

	if (real >= 0) return real;
	if (errno == EINTR || errno == EAGAIN) return real;
	
	return -WOW_FAILED;
}
int wow_socket_urecv(int nSktfd,char *pcAddr, uint16_t* u16Port,uint8_t* pu8Data, size_t snSize)
{
	CHECK_RET_VAL_P(nSktfd >= 0 && snSize > 0,-PARAM_INPUT_ARG_INVALID,"param input arg invalid!\n");
	CHECK_RET_VAL_P(pu8Data && pcAddr && u16Port, -PARAM_INPUT_DATA_IS_NULL ,"param input data invalid!\n");

	struct sockaddr_in saddr = {0};
	socklen_t  len = sizeof(struct sockaddr_in);
	int ret = recvfrom(nSktfd, pu8Data,snSize, 0, (struct sockaddr*)&saddr, &len);

	if (ret >= 0){
		if(pcAddr){
			strcpy(pcAddr,inet_ntoa(saddr.sin_addr)); 
		}
		if(u16Port){
			*u16Port = ntohs(saddr.sin_port);
		} 
		return ret;
	}
	if (errno == EINTR || errno == EAGAIN) return 0;
	
	return -WOW_FAILED;
}

发送信息

int wow_socket_tsend(int nSktfd,const uint8_t* pu8Data, size_t snSize)
{
	CHECK_RET_VAL_P(nSktfd >= 0 && snSize > 0,-PARAM_INPUT_ARG_INVALID,"param input arg invalid!\n");
	CHECK_RET_VAL_P(pu8Data , -PARAM_INPUT_DATA_IS_NULL ,"param input data invalid!\n");

	//write(nSktfd,pu8Data,snSize);
	int real = send(nSktfd, pu8Data,snSize, MSG_NOSIGNAL);

	if (real >= 0) return real;
	if (errno == EINTR || errno == EAGAIN) return real;
	
	return -WOW_FAILED;;
}

int wow_socket_usend(int nSktfd,const char *pcAddr, uint16_t u16Port,const uint8_t* pu8Data, size_t snSize)
{
	CHECK_RET_VAL_P(nSktfd >= 0 && snSize > 0,-PARAM_INPUT_ARG_INVALID,"param input arg invalid!\n");
	CHECK_RET_VAL_P(pu8Data && pcAddr && u16Port, -PARAM_INPUT_DATA_IS_NULL ,"param input data invalid!\n");;

	struct sockaddr_in saddr;
	saddr.sin_family = AF_INET;
	saddr.sin_addr.s_addr = inet_addr(pcAddr);
	saddr.sin_port = htons(u16Port);

	int ret  = sendto(nSktfd, pu8Data, snSize, 0, (struct sockaddr*)&saddr, sizeof(struct sockaddr_in));
	if (ret  >= 0) return ret;
	if (errno == EINTR || errno == EAGAIN) return ret;
	
	return -WOW_FAILED;
}

设置/获取socket参数

int wow_socket_setopt(int nSktfd, SocketCtrl_E eCtrl, ...)
{
	CHECK_RET_VAL_P(nSktfd >= 0 && eCtrl < SOCKET_CTRL_MAX,-PARAM_INPUT_ARG_INVALID,"param input arg invalid!\n");

	va_list args;
	va_start(args, eCtrl);

	switch (eCtrl)
	{
	case SOCKET_CTRL_SET_BLOCK://设置阻塞模式
		{
			int block = (int)va_arg(args, int);
			va_end(args);
			
			if (block){
				fcntl(nSktfd, F_SETFL, fcntl(nSktfd, F_GETFL) & ~O_NONBLOCK);
			} else{
				fcntl(nSktfd, F_SETFL, fcntl(nSktfd, F_GETFL) | O_NONBLOCK);
			} 
		}
		break;
	case SOCKET_CTRL_GET_BLOCK://获取阻塞模式
		{
			int* block = (int*)va_arg(args, int*);
			va_end(args);
			
			CHECK_RET_VAL_P(block, -PARAM_INPUT_DATA_IS_NULL,"param input data invalid!\n");
			*block = (fcntl(nSktfd, F_GETFL) & O_NONBLOCK)? 0 : 1;
		}
		break;
	case SOCKET_CTRL_SET_TCP_NODELAY://设置 nodelay 功能 1 表示打开,0 表示关闭
		{
			int nagle = (int)va_arg(args, int);
			va_end(args);
			int ret = setsockopt(nSktfd, IPPROTO_TCP, TCP_NODELAY, (char*)&nagle, sizeof(int));
			CHECK_RET_VAL_P_A(ret == 0, -SOCKET_SET_OPT_FAILED,"setsockopt false!\n");
		}
		break;
	case SOCKET_CTRL_GET_TCP_NODELAY://获取 nodelay 功能
		{
			// the penable
			int* nagle = (int*)va_arg(args, int*);
			va_end(args);
			CHECK_RET_VAL_P(nagle, -PARAM_INPUT_DATA_IS_NULL,"param input data invalid!\n");

			
			int enable = 0;
			socklen_t len = sizeof(enable);
			int ret = getsockopt(nSktfd, IPPROTO_TCP, TCP_NODELAY, (char*)&enable, &len);
			CHECK_RET_VAL_P_A(ret == 0, -SOCKET_GET_OPT_FAILED,"getsockopt false!\n");
			
			*nagle = enable;
		}
		break;
	case SOCKET_CTRL_SET_RECV_BUFF_SIZE://设置读缓冲区大小
		{
			int size = (int)va_arg(args, int);
			va_end(args);
			
			int ret = setsockopt(nSktfd, SOL_SOCKET, SO_RCVBUF, (char*)&size, sizeof(int));
			CHECK_RET_VAL_P_A(ret == 0, -SOCKET_SET_OPT_FAILED,"setsockopt false!\n");
		}
		break;
	case SOCKET_CTRL_GET_RECV_BUFF_SIZE://获取读缓冲区大小
		{
			int* size = (int*)va_arg(args, int*);
			va_end(args);
			CHECK_RET_VAL_P(size, -PARAM_INPUT_DATA_IS_NULL,"param input data invalid!\n");

			int  real = 0;
			socklen_t len = sizeof(real);
			int ret = getsockopt(nSktfd, SOL_SOCKET, SO_RCVBUF, (char*)&real, &len);
			CHECK_RET_VAL_P_A(ret == 0, -SOCKET_GET_OPT_FAILED,"getsockopt false!\n");

			*size = real;
		}
		break;
	case SOCKET_CTRL_SET_SEND_BUFF_SIZE://设置写缓冲区大小 
		{
			int size = (int)va_arg(args, int);
			va_end(args);
			
			int ret = setsockopt(nSktfd, SOL_SOCKET, SO_SNDBUF, (char*)&size, sizeof(int));
			CHECK_RET_VAL_P_A(ret == 0, -SOCKET_SET_OPT_FAILED,"setsockopt false!\n");
		}
		break;
	case SOCKET_CTRL_GET_SEND_BUFF_SIZE://获取写缓冲区大小 
		{
			int* size = (int*)va_arg(args, int*);
			va_end(args);
			CHECK_RET_VAL_P(size, -PARAM_INPUT_DATA_IS_NULL,"param data input invalid!\n");

			int  real = 0;
			socklen_t len = sizeof(real);
			int ret = getsockopt(nSktfd, SOL_SOCKET, SO_SNDBUF, (char*)&real, &len);
			CHECK_RET_VAL_P_A(ret == 0, -SOCKET_GET_OPT_FAILED,"getsockopt false!\n");

			*size = real;
		}
		break;
	case SOCKET_CTRL_SET_KEEPALIVE:
		{
			int enable = (int)va_arg(args, int);
			va_end(args);
			
			int ret = setsockopt(nSktfd, SOL_SOCKET, SO_KEEPALIVE, (char*)&enable, sizeof(int));
			CHECK_RET_VAL_P_A(ret == 0, -SOCKET_SET_OPT_FAILED,"setsockopt false!\n");
		}
		break;
	case SOCKET_CTRL_SET_TCP_KEEPINTVL:
		{
			int intvl = (int)va_arg(args, size_t);
			va_end(args);
			
			int ret = setsockopt(nSktfd, IPPROTO_TCP, TCP_KEEPINTVL, (char*)&intvl, sizeof(int));
			CHECK_RET_VAL_P_A(ret == 0, -SOCKET_SET_OPT_FAILED,"setsockopt false!\n");
		}
		break;
	default:
		return -WOW_FAILED;
	}


	return 0;
}

获取连接目标地址信息

int wow_socket_peerName(int nSktfd,char *pcAddr, uint16_t* u16Port)
{
	int ret = -1;
	
	CHECK_RET_VAL_P(nSktfd >= 0,-PARAM_INPUT_ARG_INVALID,"param input arg invalid!\n");
	CHECK_RET_VAL_P(pcAddr && u16Port, -PARAM_INPUT_DATA_IS_NULL ,"param input data invalid!\n");


	struct sockaddr_in saddr;
	socklen_t len = sizeof(struct sockaddr_in);
	memset(&saddr, 0, len);

	ret = getpeername(nSktfd , (struct sockaddr *)&saddr, &len);
	CHECK_RET_VAL_P_A(ret==0,-1,"getpeername false!");

	strcpy(pcAddr,inet_ntoa(saddr.sin_addr)); 
	*u16Port = ntohs(saddr.sin_port);

	return 0;
}

获取本地地址信息

int wow_socket_localName(int nSktfd,char *pcAddr, uint16_t* u16Port)
{
	CHECK_RET_VAL_P(nSktfd >= 0,-PARAM_INPUT_ARG_INVALID,"param input arg invalid!\n");
	CHECK_RET_VAL_P(pcAddr && u16Port, -PARAM_INPUT_DATA_IS_NULL ,"param input data invalid!\n");

	struct sockaddr_in saddr = {0};
	socklen_t len = sizeof(struct sockaddr_in);
	int  ret = getsockname(nSktfd, (struct sockaddr *)&saddr,&len);
	CHECK_RET_VAL_P_A(ret == 0,-1,"getsockname fasle!\n");
	
	strcpy(pcAddr,inet_ntoa(saddr.sin_addr)); 
	*u16Port = ntohs(saddr.sin_port);

	return 0;
}

相关推荐

  1. wow-socket文件说明

    2024-04-23 08:16:07       17 阅读
  2. wow-type文件说明

    2024-04-23 08:16:07       16 阅读
  3. wow-slist文件说明

    2024-04-23 08:16:07       15 阅读
  4. wow-string-list文件说明

    2024-04-23 08:16:07       18 阅读
  5. wow_iot模块说明

    2024-04-23 08:16:07       8 阅读
  6. .gitignore 文件说明文档

    2024-04-23 08:16:07       11 阅读
  7. vld.ini配置文件说明

    2024-04-23 08:16:07       13 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-23 08:16:07       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-23 08:16:07       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-23 08:16:07       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-23 08:16:07       20 阅读

热门阅读

  1. 3D抓取算法中的PointNet++网络介绍

    2024-04-23 08:16:07       13 阅读
  2. v-for和v-if的优先级

    2024-04-23 08:16:07       12 阅读
  3. Kubernetes教程:管理和扩展容器化应用

    2024-04-23 08:16:07       15 阅读
  4. 常见的css面试题(持续更新,欢迎补充)

    2024-04-23 08:16:07       14 阅读
  5. Python使用random模块随机生成ip、端口、字符串

    2024-04-23 08:16:07       15 阅读
  6. 环形链表的约瑟夫问题

    2024-04-23 08:16:07       18 阅读
  7. 【IO流】字符流和字节流

    2024-04-23 08:16:07       15 阅读
  8. asio之地址

    2024-04-23 08:16:07       14 阅读
  9. 密码学系列1-安全规约

    2024-04-23 08:16:07       14 阅读
  10. JVM加载类的流程

    2024-04-23 08:16:07       13 阅读