#define UNIX_PLATFORM #include "tcpComm.h" tcpComm::tcpComm() : m_sockfd(0),m_nCommTimeOut(0), m_nRefreshMode(0), m_nTimeFailMode(0) { } tcpComm::~tcpComm() { } bool tcpComm::Create(long nCommTimeOut, long nRefreshMode, long nTimeFailMode) { if (nCommTimeOut < 0) return false; m_nCommTimeOut = nCommTimeOut; m_nRefreshMode = nRefreshMode; m_nTimeFailMode = nTimeFailMode; return true; } int tcpComm::CreateNetServer(unsigned short nServicePort) { //int sockfd; int optval = 1; struct sockaddr_in serv_addr; m_sockfd = socket(AF_INET, SOCK_STREAM, 0); #ifdef UNIX_PLATFORM if (m_sockfd <= 0) return TCC_INVALIDVALUE; #else if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) return TCC_INVALIDVALUE; #endif memset((char *) &serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(nServicePort); setsockopt(m_sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*) &optval, sizeof(optval)); //setsockopt(sockfd, SOL_SOCKET, SO_OOBINLINE, (const char*)&optval, sizeof(optval)); #ifdef UNIX_PLATFORM if (bind(m_sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0) #else if (bind(sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == SOCKET_ERROR) #endif { TCP_CLOSE(m_sockfd); return TCC_INVALIDVALUE; } #ifdef UNIX_PLATFORM if (listen(m_sockfd, 5) < 0) #else if (listen(sockfd, 5) == SOCKET_ERROR) #endif { TCP_CLOSE(m_sockfd); return TCC_INVALIDVALUE; } return (int) m_sockfd; } int tcpComm::WaitingNetServer() { int _sockfd; struct sockaddr_in cli_addr; socklen_t clilen = sizeof(cli_addr); memset(&cli_addr, 0, sizeof(cli_addr)); _sockfd = accept(m_sockfd, (struct sockaddr*) &cli_addr, &clilen); #ifdef UNIX_PLATFORM if (_sockfd < 0) return TCC_INVALIDVALUE; #else if (_sockfd == INVALID_SOCKET) return TCC_INVALIDVALUE; #endif return (int) _sockfd; } int tcpComm::ConnectNetServer(const char * pSerIp, unsigned short nSerPort) { //int sockfd; struct sockaddr_in serv_addr; memset((char*) &serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr(pSerIp); serv_addr.sin_port = htons(nSerPort); #ifdef UNIX_PLATFORM if ((m_sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) #else if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) #endif return TCC_INVALIDVALUE; #ifdef UNIX_PLATFORM if (connect(m_sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0) #else if (connect(sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == SOCKET_ERROR) #endif { TCP_CLOSE(m_sockfd); return TCC_INVALIDVALUE; } return m_sockfd; } int tcpComm::EnableNoBlockMode(int flag) { #ifdef UNIX_PLATFORM if (flag) return fcntl(m_sockfd, F_SETFL, fcntl(m_sockfd, F_GETFL, 0) | O_NDELAY); else return fcntl(m_sockfd, F_SETFL, fcntl(m_sockfd, F_GETFL, 0) & ~O_NDELAY); #else u_long optval; if (flag) optval = 1; else optval = 0; return ioctlsocket(sockfd, FIONBIO, &optval); #endif } int tcpComm::SendData(unsigned char *send_buf, long nSize) { unsigned char *p_buf; int byte_remain; int byte_write; long timecount; /* 时间记数值(以0.01秒为单位)*/ if (send_buf == NULL) return 0; if ((m_sockfd <= 0) || (nSize <= 0) || (m_nCommTimeOut < 0)) return 0; p_buf = send_buf; /* 记录初始指针 */ byte_remain = (int) nSize; /* 记录期望的读数值 */ byte_write = 0; /* 实际读数值 */ timecount = 0; /* 初始化超时时间 */ while ((timecount <= m_nCommTimeOut) && (byte_remain > 0)) { #ifdef UNIX_PLATFORM switch (byte_write = write(m_sockfd, p_buf, byte_remain)) /* 发送数据 */ #else switch (byte_write = send(sockfd, (char*) p_buf, byte_remain, 0)) /* 发送数据 */ #endif { case SOCKET_ERROR: #ifdef UNIX_PLATFORM if (errno == EWOULDBLOCK) /* 非阻塞方式 */ #else if (WSAGetLastError() == WSAEWOULDBLOCK) /* 非阻塞方式 */ #endif { if (m_nCommTimeOut > 0) TCP_DELAY(10); /* 如果要求延时 */ timecount++; /* 延时计数器加1 */ break; } else return TCC_INVALIDVALUE; /* 其他错误(例如EINTR信号中断) */ case 0: if (m_nCommTimeOut > 0) TCP_DELAY(10); /* 如果要求延时 */ timecount++; /* 延时计数器加1 */ break; default: if (m_nRefreshMode) timecount = 0; /* 重新记时 */ byte_remain -= byte_write; /* 修改剩余的发送字节数 */ p_buf += byte_write; /* 移动缓冲指针 */ byte_write = 0; /* 重新记数发送的字节数 */ } } if ((m_nTimeFailMode) && (timecount >= m_nCommTimeOut)) /* 超时断情况 */ return TCC_INVALIDVALUE; return (nSize - byte_remain); /* 返回实际发送字节数 */ } int tcpComm::SendFile(char *filename) { int byte_write; int byte_block; int byte_ret; int timeout_times; struct stat filestat; FILE* fp_data; unsigned char * m_pFileTransBuf; // 文件传输块 long m_nTransBlkSize = 2048; // 文件传输块大小 if (stat(filename, &filestat) != 0) return 0; byte_write = 0; timeout_times = 0; m_pFileTransBuf = new unsigned char[m_nTransBlkSize]; if (m_pFileTransBuf == NULL) return -1; if ((fp_data = fopen(filename, "rb")) == NULL) { delete m_pFileTransBuf; return 0; } while ((byte_write < filestat.st_size) && (timeout_times < 3)) { byte_block = (int) (filestat.st_size - byte_write); if (byte_block > m_nTransBlkSize) byte_block = (int) m_nTransBlkSize; fseek(fp_data, byte_write, SEEK_SET); fread(m_pFileTransBuf, sizeof(char), byte_block, fp_data); byte_ret = SendData(m_pFileTransBuf, byte_block); if (byte_ret < 0) break; if (byte_ret == 0) timeout_times++; if (byte_ret > 0) timeout_times = 0; byte_write += byte_ret; } fclose(fp_data); delete m_pFileTransBuf; if (byte_ret < 0) return TCC_INVALIDVALUE; // 通信出错 if (timeout_times >= 3) return TCC_INVALIDVALUE; // 通信出错 if (byte_write != filestat.st_size) return 0; else return filestat.st_size; } int tcpComm::RecvData(unsigned char *recv_buf, long nSize) { unsigned char *p_buf; int byte_remain; int byte_read; long timecount; /* 时间记数值(以0.01秒为单位)*/ if (recv_buf == NULL) return 0; if ((m_sockfd <= 0) || (nSize <= 0) || (m_nCommTimeOut < 0)) return 0; p_buf = recv_buf; /* 记录初始指针 */ byte_remain = (int) nSize; /* 记录期望的读数值 */ byte_read = 0; /* 实际读数值 */ timecount = 0; /* 计算超时时间 */ while ((timecount <= m_nCommTimeOut) && (byte_remain > 0)) { #ifdef UNIX_PLATFORM switch (byte_read = read(m_sockfd, p_buf, byte_remain)) /* 接收数据 */ #else switch (byte_read = recv(sockfd, (char *) p_buf, byte_remain, 0)) #endif { case SOCKET_ERROR: #ifdef UNIX_PLATFORM if (errno == EWOULDBLOCK) /* 非阻塞方式 */ #else if (WSAGetLastError() == WSAEWOULDBLOCK) /* 非阻塞方式 */ #endif { if (m_nCommTimeOut > 0) TCP_DELAY(10); /* 如果要求延时 */ timecount++; /* 延时计数器加1 */ break; } else return TCC_INVALIDVALUE; /* 其他错误(例如EINTR信号中断) */ case 0: return TCC_INVALIDVALUE; /* 网络中断 */ default: if (m_nRefreshMode) timecount = 0; /* 重新记时 */ byte_remain -= byte_read; /* 修改剩余的读取字节数 */ p_buf += byte_read; /* 移动缓冲指针 */ byte_read = 0; /* 重新记数读到的字节数 */ } } if ((m_nTimeFailMode) && (timecount >= m_nCommTimeOut)) /* 超时断情况 */ return TCC_INVALIDVALUE; return (nSize - byte_remain); } int tcpComm::RecvFile(char *filename, long nSize) { int byte_read; int byte_block; int byte_ret; int timeout_times; FILE *fp_data; unsigned char * m_pFileTransBuf; // 文件传输块 long m_nTransBlkSize = 2048; // 文件传输块大小 if (nSize <= 0) return 0; byte_read = 0; timeout_times = 0; m_pFileTransBuf = new unsigned char[m_nTransBlkSize]; if (m_pFileTransBuf == NULL) return -1; if ((fp_data = fopen(filename, "wb")) == NULL) { delete m_pFileTransBuf; return 0; } while ((byte_read < nSize) && (timeout_times < 3)) { byte_block = (int) (nSize - byte_read); if (byte_block > m_nTransBlkSize) byte_block = (int) m_nTransBlkSize; byte_ret = RecvData(m_pFileTransBuf, byte_block); if (byte_ret < 0) break; if (byte_ret == 0) timeout_times++; if (byte_ret > 0) { fwrite(m_pFileTransBuf, sizeof(char), byte_ret, fp_data); timeout_times = 0; } byte_read += byte_ret; } fclose(fp_data); delete m_pFileTransBuf; if (byte_ret < 0) return TCC_INVALIDVALUE; // 通信出错 if (timeout_times >= 3) return TCC_INVALIDVALUE; // 通信出错 if (byte_read != nSize) return 0; return nSize; } int tcpComm::CloseComm() { int iRet = -1; if (m_sockfd <= 0) return 0; #ifdef UNIX_PLATFORM iRet = shutdown(m_sockfd, SHUT_RDWR); #else iRet = shutdown(sockfd, SD_BOTH); #endif if (0 == iRet) { return TCP_CLOSE(m_sockfd); } else return iRet; }