#include "stdafx.h"
#include "TCP.h"
#include "CDV.h"
void Task(LPVOID param)
{
CTCP * pTcp = (CTCP *)param;
//while (pTcp->Recv()>=0);
}
CTCP::CTCP()
{
m_connectSocket = INVALID_SOCKET;
}
CTCP::~CTCP()
{
CloseConnect();
}
CTCP::CTCP(PCSTR ip, PCSTR port)
{
m_ip = ip;
m_port = port;
m_connectSocket = INVALID_SOCKET;
if (ConnectServer(ip, port));
}
void CTCP::StartTask()
{
_beginthread(Task, 0, this);
}
//-1失败
int CTCP::ConnectServer(PCSTR ip, PCSTR port, bool notice)
{
CloseConnect();
m_ip = ip;
m_port = port;
WSADATA wsaData;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
int iResult;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
if (notice)
::AfxMessageBox(_T("网络连接失败"), MB_ICONWARNING, TRUE);
return -1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo(ip, port, &hints, &result);
if (iResult != 0) {
WSACleanup();
if (notice)
::AfxMessageBox(_T("网络连接失败"), MB_ICONWARNING, TRUE);
return -1;
}
// Attempt to connect to an address until one succeeds
for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {
// Create a SOCKET for connecting to server
m_connectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (m_connectSocket == INVALID_SOCKET) {
WSACleanup();
if (notice)
::AfxMessageBox(_T("网络连接失败"), MB_ICONWARNING, TRUE);
return -1;
}
int iMode = 1;
ioctlsocket(m_connectSocket, FIONBIO, (u_long FAR*)&iMode);
// Connect to server.
iResult = connect(m_connectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
struct timeval tm;
tm.tv_sec = 5;
tm.tv_usec = 0;
int ret = -1;
// 尝试去连接服务端
if (-1 != iResult)
{
ret = 1; // 连接成功
}
else
{
fd_set set;
FD_ZERO(&set);
FD_SET(m_connectSocket, &set);
int sel = select(-1, NULL, &set, NULL, &tm);
if (sel <= 0)
{
ret = -1; // 有错误
}
else if (FD_ISSET(m_connectSocket, &set))
{
int error = -1;
int optLen = sizeof(int);
int get = getsockopt(m_connectSocket, SOL_SOCKET, SO_ERROR, (char*)&error, &optLen);
if (0 != error)
{
ret = -1; // 有错误
}
else
{
ret = 1; // 无错误
}
}
}
iMode = 0;
ioctlsocket(m_connectSocket, FIONBIO, (u_long FAR*)&iMode);
if (-1 == ret) {
closesocket(m_connectSocket);
m_connectSocket = INVALID_SOCKET;
}
}
freeaddrinfo(result);
char tbuf[10] = "hello";
//int ret = Send(tbuf, 5);
int ret = Recv(tbuf, 10, 10);
if (-1 == ret || m_connectSocket == INVALID_SOCKET) {
WSACleanup();
if (notice)
{
GGStop = -1;//2670 打开NPC项目,显示网络连接失败,打开某一个路径后,右下角显示网络状态已连接,大概3秒之后会显示网络未连接(实际状态未连接)
//::AfxMessageBox(_T("网络连接失败"), MB_ICONWARNING, TRUE);
}
return -1;
}
if (notice)
{
GGStop = 1;
//::AfxMessageBox(_T("恭喜,网络连接成功!"), MB_ICONWARNING, TRUE);
}
return 0;
}
int CTCP::ConnectServer(CString ip, UINT port)
{
CString csPort;
csPort.Format("%d", port);
int ret = ConnectServer(ip.GetBuffer(), csPort.GetBuffer());
ip.ReleaseBuffer();
csPort.ReleaseBuffer();
return ret;
}
int CTCP::ConnectServer(CString ip, CString port, bool notice)
{
if (!notice)
{
int ret = ConnectServer(ip.GetBuffer(), port.GetBuffer(),false);
ip.ReleaseBuffer();
port.ReleaseBuffer();
return ret;
}
}
int CTCP::CloseConnect()
{
if (m_connectSocket == INVALID_SOCKET)
return 0;
// shutdown the connection since no more data will be sent
int iResult = shutdown(m_connectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
closesocket(m_connectSocket);
WSACleanup();
return -1;
}
// Receive until the peer closes the connection
/*int timeout = 100;
int ret = setsockopt(m_connectSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
do {
char recvbuf[100];
iResult = recv(m_connectSocket, recvbuf, 100, 0);
} while (iResult > 0);*/
Clean();
// cleanup
closesocket(m_connectSocket);
WSACleanup();
return 0;
}
//-1连接出错close
int CTCP::Send(char * buf, int len)
{
int step = 250;
int delay = 5;
int iResult;
int i = 0;
if (m_connectSocket == INVALID_SOCKET)
return -1;
int senBuflen;
/* int size = sizeof(senBuflen);
int ret = getsockopt(m_connectSocket, SOL_SOCKET, SO_SNDBUF, (char*)&senBuflen, &size);
senBuflen = len;// 0x10000;
ret = setsockopt(m_connectSocket, SOL_SOCKET, SO_SNDBUF, (char*)&senBuflen, size);
ret = getsockopt(m_connectSocket, SOL_SOCKET, SO_MAX_MSG_SIZE, (char*)&senBuflen, &size);
*/
//for (i = 0; i < len; ) {
// if (i + step <= len)
// {
// }
// else
// {
// step = len - i;
// }
// iResult = send(m_connectSocket, buf + i, step, 0);
// if (iResult < step) {
// int error = WSAGetLastError();
// if (iResult == SOCKET_ERROR) {
// return -1;
// }
// else
// {
// i += iResult;
// }
// }
// else if(iResult == step)
// {
// i += step;
// }
// else
// {
// }
// //Sleep(delay);
//}
iResult = send(m_connectSocket, buf, len, 0);
return 0;
}
//返回接收长度
//-1连接出错close
int CTCP::Recv(char * buf, int len, int timeout)
{
if (m_connectSocket == INVALID_SOCKET)
return -1;
// Receive until the peer closes the connection
int ret = setsockopt(m_connectSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
int iResult;
int rlen = 0;
/*while (rlen < len)
{*/
iResult = recv(m_connectSocket, buf + rlen, len, 0);
int error = WSAGetLastError();
if (iResult > 0)
{
rlen += iResult;
}
else if (WSAETIMEDOUT == error)
{
return 0;
}
else
{
return -1;
}
//}
return rlen;
}
//返回接收长度
//-1连接出错close
int CTCP::Recv1(char * buf, int len, int timeout)
{
if (m_connectSocket == INVALID_SOCKET)
return -1;
// Receive until the peer closes the connection
int ret = setsockopt(m_connectSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
int iResult;
int rlen = 0;
while (rlen < len)
{
iResult = recv(m_connectSocket, buf + rlen, len, 0);
int error = WSAGetLastError();
if (iResult > 0)
{
rlen += iResult;
}
else if (WSAETIMEDOUT == error)
{
return 0;
}
else
{
return -1;
}
}
return rlen;
}
void CTCP::Clean()
{
int iResult;
int timeout = 1;
int ret = setsockopt(m_connectSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
do {
char recvbuf[100];
iResult = recv(m_connectSocket, recvbuf, 100, 0);
} while (iResult > 0);
return;
}
int CTCP::NPC_SendAndRecv(char * sbuf, int slen, char * rbuf, int rlen, bool *bcrc, int rTimeout, bool notice)
{
ASSERT(sbuf && rbuf);
int ret = 0;
bool bret = false;
unsigned short crc = 0;
if (bcrc && slen)
{
crc = getCRC16(sbuf, slen);
char temp1 = crc & 0xff;
char temp0 = (crc >> 8) & 0xff;
sbuf[slen] = temp1;
sbuf[slen + 1] = temp0;
slen += 2;
}
Clean();
if (slen)
ret = Send(sbuf, slen);
if (-1 < ret)
ret = Recv(rbuf, rlen, rTimeout);
if (ret > -1)
{
if (ret > 2 && bcrc)
{
crc = getCRC16(rbuf, ret - 2);
if (((char)(crc & 0xff) == rbuf[ret - 2]) && ((char)((crc >> 8) & 0xff) == rbuf[ret - 1]))
{
bret = true;
}
else
{
bret = false;
}
}
}
else
{
if (!notice /*|| IDOK == AfxMessageBox(_T("发送接收失败,是否尝试连接!"), MB_OKCANCEL, TRUE)*/)
{
ConnectServer(m_ip, m_port, false);
}
}
if (bcrc)
*bcrc = bret;
return ret;
}
int CTCP::NPC_Recv(char * rbuf, int rlen, bool *bcrc, int rTimeout, bool notice)
{
int ret = 0; //5.20 原不注释
bool bret = false;
unsigned short crc = 0;
//5.20
//int ret = 0;
//bool bret = false;
//unsigned short crc = 0;
//if (bcrc && rlen)
//{
// crc = getCRC16(rbuf, rlen);
// char temp1 = crc & 0xff;
// char temp0 = (crc >> 8) & 0xff;
// rbuf[rlen] = temp1;
// rbuf[rlen + 1] = temp0;
// rlen += 2;
//}
Clean();
ret = Recv1(rbuf, rlen, rTimeout);
if (ret > -1)
{
if (ret > 2 && bcrc)
{
crc = getCRC16(rbuf, ret - 2);
if (((char)(crc & 0xff) == rbuf[ret - 2]) && ((char)((crc >> 8) & 0xff) == rbuf[ret - 1]))
{
bret = true;
}
else
{
bret = false;
}
}
}
//else
//{
// if (!notice /*|| IDOK == AfxMessageBox(_T("发送接收失败,是否尝试连接!"), MB_OKCANCEL, TRUE)*/)
// {
// ConnectServer(m_ip, m_port, false);
// }
//}
if (bcrc)
*bcrc = bret;
return ret;
}