📄 cutil-socket.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 + -