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

📄 cutil-socket.c

📁 Linux环境下常用功能的实现
💻 C
字号:
#include "cutil.h"static pthread_mutex_t gstruMutex = PTHREAD_MUTEX_INITIALIZER;/** * cutil_socket_new: * @pszHost:IP地址或者主机名称 * @nPort:监听端口 * @nListen: 1要求建立监听端口.0建立到服务器的连接 * * 创建一个到指定服务器的TCP连接(@nListen = 0). * 创建一个本地的监听端口(@nListen = 1) * * Returns: 成功返回套接字描述符号.失败返回-1 */int cutil_socket_new(const char *pszHost, int nPort, int nListen){	int nFD;	struct sockaddr_in struAddr;	struct hostent *pstruHost;	memset(&struAddr, 0, sizeof(struAddr));	if(pszHost)	{		if(inet_aton(pszHost, (struct in_addr *)&struAddr.sin_addr) == 0)		{			pthread_mutex_lock(&gstruMutex);			pstruHost = gethostbyname(pszHost);			if(pstruHost == NULL)			{				cutil_log_error(N_(" get host :%s ip address error:%s\n"),					pszHost, hstrerror(h_errno));				pthread_mutex_unlock(&gstruMutex);				return -1;			}			struAddr.sin_addr = 				*(struct in_addr *)pstruHost -> h_addr_list[0];			pthread_mutex_unlock(&gstruMutex);		}	}	else	{		if(nListen != 1)		{			cutil_log_error(N_("NULL host is allowed only in listinging state"));			return -1;		}		struAddr.sin_addr.s_addr = INADDR_ANY;	}	struAddr.sin_family = AF_INET;	struAddr.sin_port = htons(nPort);		nFD = socket(AF_INET, SOCK_STREAM, 0);	if(nFD == -1)	{		cutil_log_error(N_(" create AF_INET socket error:%s\n"),				strerror(errno));		return -1;	}		if(nListen)	{		int nVal = 1;		if(setsockopt(nFD, SOL_SOCKET, SO_REUSEADDR, &nVal, sizeof(nVal)) < 0)		{			cutil_log_error(N_("set socket SO_REUSEADDR error:%s\n"),				strerror(errno));			close(nFD);			return -1;			}		if(bind(nFD, (struct sockaddr *)&struAddr, sizeof(struAddr)) == -1)		{			cutil_log_error(N_(" bind address %s:%d error:%s\n"),				pszHost, nPort, strerror(errno));			close(nFD);			return -1;		}		listen(nFD, 10);		return nFD;	}	if(connect(nFD, (struct sockaddr *)&struAddr, 			sizeof(struAddr)) == -1)	{		cutil_log_error(N_("connect to server %s:%d error:%s\n"),				pszHost, nPort, strerror(errno));		return -1;	}	return nFD;}/** * cutil_socket_set_timeout: * @nFD: 要求设置超时的描述符号 * @nTimeOut:设定的超时时间.以秒为单位 * * 设定网络SOCKET的超时时间 */void cutil_socket_set_timeout(int nFD, int nTimeOut){	struct timeval struTimeOut;	memset(&struTimeOut, 0, sizeof(struTimeOut));	struTimeOut.tv_sec = nTimeOut;	struTimeOut.tv_usec = 0;	if((setsockopt(nFD, SOL_SOCKET,	SO_SNDTIMEO, &struTimeOut, 			sizeof(struTimeOut)) < 0) ||		setsockopt(nFD, SOL_SOCKET, SO_RCVTIMEO, &struTimeOut,			sizeof(struTimeOut)))	{		cutil_log_error(N_(" set socket timeout error:%s\n"), 			strerror(errno));	}}/** * cutil_socket_send: * @nFD:要求发送数据套接字 * @pszSendBuffer:要求发送的报文 * @nLen:要求发送的报文长度 * * 向套接字发送一个指定长度的报文 * * Returns:成功返回发送的长度.失败返回-1 */int cutil_socket_send(int nFD, const char *pszSendBuffer, int nLen){	char *p = (char *)pszSendBuffer;	int nSendLen;	int nLeftLen = nLen;	while(nLeftLen > 0)	{		nSendLen = write(nFD, p, nLeftLen);		if((nSendLen <= 0) && (errno != EINTR))		{			cutil_log_error(N_(" send socket buffer error:%s\n"), 				strerror(errno));			return -1;		}		p += nSendLen;		nLeftLen -= nSendLen;	}	return nLen;}/** * cutil_socket_recv: * @nFD:要求接收数据的连接 * @pszRecvBuffer:要求接收的报文 * @nLen:要求接收的报文长度 * * 从连接接收一个指定长度的报文 * * Returns:成功返回接收的长度.失败返回-1 */int cutil_socket_recv(int nFD, char *pszRecvBuffer, int nLen){	char *p = pszRecvBuffer;	int nRecvLen;	int nLeftLen = nLen;	while(nLeftLen > 0)	{		nRecvLen = read(nFD, p, nLeftLen);		if((nRecvLen <= 0) && (errno != EINTR))		{			cutil_log_error(N_(" recv socket buffer error:%s\n"), 				strerror(errno));			return -1;		}		p += nRecvLen;		nLeftLen -= nRecvLen;	}	return nLen;}/** * cutil_socket_get_state: * @nFD:要求获取状态的连接 * * 获取网络连接的状态 * * Returns: -1连接被断开, 0连接正常且无数据可读, 1连接正常且有数据可读取 */int cutil_socket_get_state(int nFD){	fd_set struReadSet;	struct timeval struTimeOut;	char c;	FD_ZERO(&struReadSet);	FD_SET(nFD,&struReadSet);	struTimeOut.tv_sec = 0;	struTimeOut.tv_usec = 100;	switch(select(nFD + 1,&struReadSet,NULL,NULL,&struTimeOut))	{		case 0:			return 0;			break;		case -1:			return -1;			break;		case 1:			if(recv(nFD, &c,1,MSG_PEEK) == 1)				return 1;			else				return -1;			break;	}	return -1;}/** * cutil_socket_put_line: * @nFD:要求发送数据的连接 * @pszBuffer:要求发送的报文 * @nCR:是否要求发送\r字符 1发送0不发送 * * 发送一行数据到网络(\r\n) * * Returns:成功返回0.失败返回-1 */int cutil_socket_put_line(int nFD, const char *pszBuffer, int nCR){	int nLen = strlen(pszBuffer);	if(cutil_socket_send(nFD, pszBuffer, nLen) != nLen)	{		cutil_log_error(N_("send line buffer error\n"));		return -1;	}	if(nCR)	{		if(cutil_socket_send(nFD, "\r\n", 2) != 2)		{			cutil_log_error(N_("send line end error\n"));			return -1;		}	}	else	{		if(cutil_socket_send(nFD, "\n", 1) != 1)		{			cutil_log_error(N_("send line end error\n"));			return -1;		}	}	return 0;}/** * cutil_socket_get_line: * @nFD:要求接收数据的连接 * @pszBuffer:要求接收的报文 * @nMaxLen:要求接收的报文最大长度 * * 从连接接收一行数据 * * Returns:成功返回接收的长度.失败返回-1 */int cutil_socket_get_line(int nFD, char *pszBuffer, int nMaxLen){	int nLen;	char *p = pszBuffer;	nLen = 0;	while(1)	{		if(cutil_socket_recv(nFD, p, 1) != 1)		{			cutil_log_error(N_("get line buffer error\n"));			return -1;		}		nLen ++;		if(*p == '\n')		{			if((nLen > 1) && (*(p - 1) == '\r'))			{				*(p - 1) = 0;				nLen --;			}			else			{				*p = 0;			}			nLen --;			break;		}		p ++;		if(nLen >= nMaxLen)		{			cutil_log_error(N_("line buffer too min\n"));			return -1;		}	}	return nLen;}

⌨️ 快捷键说明

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