ServerLink.cpp
资源名称:smpplib.zip [点击查看]
上传用户:hkcoast
上传日期:2007-01-12
资源大小:979k
文件大小:8k
源码类别:
手机短信编程
开发平台:
Visual C++
- // ServerLink.cpp: implementation of the CServerLink class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- //#include "SMPPAPI.h"
- #include "ServerLink.h"
- #include "common.h"
- #include "smpp.h"
- #include "smpppacket.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[]=__FILE__;
- #define new DEBUG_NEW
- #endif
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- CServerLink::CServerLink() : m_bConnected(false), m_nSocket(INVALID_SOCKET),
- m_hEvent(WSA_INVALID_EVENT), m_bReadHeader(true)
- {
- m_nSocket = NULL;
- m_hEvent = NULL;
- m_hThread = NULL;
- m_pIOWinThread = NULL;
- //manual reset Kill event with intial signal state to false
- m_hKillEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- m_hDisconnectEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- //callback
- m_Param = NULL;
- m_pProcessPacket = NULL;
- InitializeCriticalSection(&m_cs);
- }
- CServerLink::CServerLink(CString svrip) : m_bConnected(false), m_nSocket(INVALID_SOCKET),
- m_hEvent(WSA_INVALID_EVENT), m_bReadHeader(true)
- {
- m_ServerIP = svrip;
- m_ServerPort = DEFAULT_PORT;
- m_nSocket = NULL;
- m_hEvent = NULL;
- m_hThread = NULL;
- m_pIOWinThread = NULL;
- //manual reset Kill event with intial signal state to false
- m_hKillEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- m_hDisconnectEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- //callback
- m_Param = NULL;
- m_pProcessPacket = NULL;
- InitializeCriticalSection(&m_cs);
- }
- CServerLink::CServerLink(CString svrip, int port) : m_bConnected(false), m_nSocket(INVALID_SOCKET),
- m_hEvent(WSA_INVALID_EVENT), m_bReadHeader(true)
- {
- m_ServerIP = svrip;
- m_ServerPort = port;
- m_nSocket = NULL;
- m_hEvent = NULL;
- m_hThread = NULL;
- m_pIOWinThread = NULL;
- //manual reset Kill event with intial signal state to false
- m_hKillEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- m_hDisconnectEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- //callback
- m_Param = NULL;
- m_pProcessPacket = NULL;
- InitializeCriticalSection(&m_cs);
- }
- CServerLink::~CServerLink()
- {
- SetEvent(m_hKillEvent);
- WaitForSingleObject(m_hThread, 500);
- CloseHandle(m_hKillEvent);
- WSACloseEvent(m_hEvent);
- CloseHandle(m_hDisconnectEvent);
- DeleteCriticalSection(&m_cs);
- }
- void CServerLink::init(CString svrip, int port)
- {
- m_ServerIP = svrip;
- m_ServerPort = port;
- }
- bool CServerLink::open()
- {
- EnterCriticalSection(&m_cs);
- bool bConnected = m_bConnected;
- LeaveCriticalSection(&m_cs);
- if (bConnected)
- return true;
- SOCKADDR_IN saServer;
- saServer.sin_port = htons(m_ServerPort);
- saServer.sin_family = AF_INET;
- saServer.sin_addr.s_addr = inet_addr(m_ServerIP);
- m_nSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (m_nSocket == INVALID_SOCKET)
- {
- return FALSE;
- }
- int nRet = connect(m_nSocket,(sockaddr*)&saServer, sizeof(saServer));
- if (nRet == SOCKET_ERROR)
- {
- TCHAR buf[100];
- sprintf(buf, "connect error %ld",WSAGetLastError());
- closesocket(m_nSocket);
- return FALSE;
- }
- ResetEvent(m_hDisconnectEvent);
- m_bConnected = TRUE;
- TRACE("Connected to Server");
- //listen to event
- m_hEvent = WSACreateEvent();
- //first, we tell the system what event we are interested
- nRet = WSAEventSelect(m_nSocket,
- m_hEvent,
- FD_CLOSE | FD_READ);
- //create the thread to listen for events
- m_pIOWinThread = AfxBeginThread(IOThreadProc, //thread proc
- (void*) this, //parameter
- THREAD_PRIORITY_NORMAL, //thread priority
- 0, //stack size
- CREATE_SUSPENDED, //create thread
- NULL); //security attribute
- m_dwThreadId = m_pIOWinThread->m_nThreadID;
- m_hThread = m_pIOWinThread->m_hThread;
- m_pIOWinThread->ResumeThread();
- TRACE("Listen TID=%ldn",m_dwThreadId);
- return TRUE;
- }
- void CServerLink::close()
- {
- EnterCriticalSection(&m_cs);
- if (m_bConnected)
- {
- SetEvent(m_hKillEvent);
- WaitForSingleObject(m_hThread, 2000);
- closesocket(m_nSocket);
- SetEvent(m_hDisconnectEvent);
- m_bConnected = FALSE;
- }
- LeaveCriticalSection(&m_cs);
- }
- bool CServerLink::isConnected()
- {
- return m_bConnected;
- }
- CString CServerLink::getServerIP()
- {
- return m_ServerIP;
- }
- int CServerLink::getServerPort()
- {
- return m_ServerPort;
- }
- UINT CServerLink::IOThreadProc(LPVOID pParam)
- {
- return ((CServerLink *) pParam)->IOThreadRun();
- }
- unsigned CServerLink::IOThreadRun()
- {
- bool bRunning = false;
- bool bConnected;
- TRACE("Going to run the IO Threadn");
- while (!bRunning)
- {
- EnterCriticalSection(&m_cs);
- bConnected = m_bConnected;
- LeaveCriticalSection(&m_cs);
- //if it's not connected exit the IO thread
- if(!m_bConnected)
- break;
- //going to shutdown, exit the loop
- if (WaitForSingleObject(m_hKillEvent, 0) == WAIT_OBJECT_0)
- {
- TRACE("Existing IO Thread coz of kill eventn");
- break;
- }
- DWORD ret = ::WSAWaitForMultipleEvents(1, &m_hEvent, FALSE, 100, FALSE);
- if (ret == WSA_WAIT_EVENT_0 ) //an event is signalled
- {
- WSANETWORKEVENTS hNetworkEvent;
- //evaluate what's happend, read or close ?
- int ret1 = ::WSAEnumNetworkEvents(m_nSocket, m_hEvent, &hNetworkEvent);
- if (hNetworkEvent.lNetworkEvents & FD_CLOSE)
- {
- TRACE("Network event is Closen");
- OnClose();
- break;
- }
- if (hNetworkEvent.lNetworkEvents & FD_READ) //we got something to read
- {
- TRACE("Network event is Readn");
- OnRead();
- }
- } //wait_object_0
- } //while bRunning
- TRACE("Exiting IO Threadn");
- return 0; //thread exit normally
- }
- bool CServerLink::OnRead()
- {
- TRACE("OnRead - CServerLinkn");
- int ret;
- if (m_bReadHeader)
- {
- m_nTotalRead = 0;
- DWORD dwRead = 0;
- //check how many bytes we could read
- ioctlsocket(m_nSocket, FIONREAD, &dwRead);
- //can we get the preliminary header ?
- //we know the packet size after reading it
- if (dwRead < 4)
- return false;
- BYTE pkt_hdr[4];
- ret = recv(m_nSocket, (char *) pkt_hdr, 4,0);
- m_nTotalRead = 4; //CommandLen is included in the length
- m_nBlockSize = readInt(pkt_hdr);
- TCHAR buff[100];
- sprintf(buff, "CommandLen is : %dn", m_nBlockSize);
- TRACE(buff);
- m_bReadHeader = FALSE; //we don't have to read header later
- }
- else
- {
- //we have already read the 4-byte preliminary header
- DWORD dwRead = 0;
- //check that how many bytes we can read
- ioctlsocket(m_nSocket, FIONREAD, &dwRead);
- if (dwRead == 0)
- return false;
- //we should only read the socket up to packet size as in the header
- if (dwRead > (m_nBlockSize - m_nTotalRead))
- dwRead = m_nBlockSize - m_nTotalRead;
- BYTE* pBlock = new BYTE[dwRead+1];
- ZeroMemory(pBlock, dwRead+1);
- int nrec = recv(m_nSocket, (char*) pBlock, dwRead, 0);
- pBlock[dwRead] = NULL;
- m_nTotalRead+=nrec;
- if (m_nTotalRead == m_nBlockSize)
- {
- //we get the whole packet in pBlock
- parse_packet(pBlock, m_nTotalRead);
- //resetting
- m_bReadHeader = TRUE;
- }
- delete [] pBlock;
- }
- return false;
- }
- bool CServerLink::OnClose()
- {
- close();
- CLinkClose *ppak = new CLinkClose();
- //call back
- if (m_pProcessPacket != NULL)
- {
- m_pProcessPacket(ppak, m_Param);
- }
- delete ppak;
- return true;
- }
- int CServerLink::send(PBYTE data, uint32 datalen)
- {
- WSABUF sbuffer;
- ULONG cb_written, retcode = 0;
- int ret;
- if (!m_bConnected)
- return 0;
- sbuffer.len = datalen;
- sbuffer.buf = (char *) data;
- retry:
- //send
- ret = WSASend (m_nSocket, (LPWSABUF)&sbuffer, 1, &cb_written, 0, NULL, NULL);
- if (ret != 0) {
- ret = WSAGetLastError();
- if (ret == WSAEWOULDBLOCK) {
- Sleep(100);
- goto retry;
- }
- return ret;
- }
- if (datalen != cb_written) {
- // not all data send!
- return -1;
- }
- return 0;
- }
- bool CServerLink::sendPacket(CPacketBase &pak)
- {
- bool ret;
- PBYTE pby;
- int nsz;
- pak.encodeBody(pby, nsz);
- if( send(pby, nsz) > 0)
- ret = true;
- else
- ret = false;
- delete [] pby;
- return ret;
- }
- void CServerLink::registerProcessPacket(void(__stdcall *start_address)(CPacketBase *pak, LPVOID param), LPVOID param)
- {
- m_pProcessPacket = start_address;
- m_Param = param;
- }