#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;
|
|
}
|