www.pudn.com > udpsocket.rar > UdpSocket.cpp
/***************************************************************** Description: The definition for the class "CUdpSocket". Author: tief@mail.eastcomtd.com Created date: 2002/10/30 14:00 PM *****************************************************************/ #include "UdpSocket.h" #include#ifdef WIN32 #include #endif #ifdef VXWORKS 0 #include #include #include #endif #include #ifdef _DEBUG #include #endif #ifdef VXWORKS 0 #define INVALID_SOCKET ERROR #define SOCKET_ERROR ERROR #endif CUdpSocket::CUdpSocket() { #ifdef WIN32 WSADATA wsd ; // Load the windows socket DLLs and initialize // the members. WSAStartup(MAKEWORD(2,2),&wsd) ; m_hThread = NULL ; #endif #ifdef VXWORKS 0 m_hTask = NULL ; #endif m_wm = user_receive ; m_bReady = false ; m_sockSender = NULL ; m_sockReceiver = NULL ; m_tvDelay.tv_sec=0 ; m_tvDelay.tv_usec=1 ; memset(&m_addrRemote,0,sizeof(SOCKADDR)) ; } STATUS CUdpSocket::SetWorkMode(workmode wm) { if (m_bReady) return CANNOT_SETMODE ; m_wm = wm ; return OK ; } STATUS CUdpSocket::Init (int localport,const char * targetip,int remoteport) { // Create the socket for data sending if ((m_sockSender=socket(AF_INET,SOCK_DGRAM,0)) ==INVALID_SOCKET) { #ifdef _DEBUG printf("run time error:") ; printf("cann't create sender (socket).\n") ; #endif OnInitComplete(SOCKET_CALL_FAILD) ; return SOCKET_CALL_FAILD ; } // Set port and remote host for sender m_addrRemote.sin_family=AF_INET ; m_addrRemote.sin_port=htons((short)remoteport) ; m_addrRemote.sin_addr.s_addr=inet_addr(targetip) ; // Create the socket for data sending if ((m_sockReceiver=socket(AF_INET,SOCK_DGRAM,0)) ==INVALID_SOCKET) { #ifdef _DEBUG printf("run time error:") ; printf("cann't create receiver (socket).\n") ; #endif OnInitComplete(SOCKET_CALL_FAILD) ; return SOCKET_CALL_FAILD ; } // Set port for receiver m_addrLocal.sin_family=AF_INET ; m_addrLocal.sin_port=htons((short)localport) ; m_addrLocal.sin_addr.s_addr=htonl(INADDR_ANY) ; if (bind(m_sockReceiver,(SOCKADDR*)&m_addrLocal, sizeof(m_addrLocal))==SOCKET_ERROR) { #ifdef _DEBUG printf("run time error:") ; printf("cann't create receiver (bind).\n") ; #endif OnInitComplete(BIND_CALL_FAILD) ; return BIND_CALL_FAILD ; } if (m_wm==auto_receive) { // Start the thread(task) for data receiving #ifdef WIN32 m_hThread = CreateThread(NULL,NULL, (LPTHREAD_START_ROUTINE)recvsrv,this,NULL,NULL) ; #ifdef _DEBUG printf("threadid 0x%x loaded.\n",m_hThread) ; #endif // _DEBUG if (m_hThread==NULL) { #ifdef _DEBUG printf("run time error:") ; printf("cann't start receiver (thread).\n") ; #endif // _DEBUG OnInitComplete(THREAD_CALL_FAILD) ; return THREAD_CALL_FAILD ; } #endif // WIN32 #ifdef VXWORKS 0 m_hTask = taskSpawn("recvsrv1",60,VX_FP_TASK, 1024*40,(FUNCPTR)recvsrv,(int)this, 0,0,0,0,0,0,0,0,0 ) ; if (m_hTask==ERROR) { #ifdef _DEBUG printf("run time error:") ; printf("cann't start receiver (task).\n") ; #endif // _DEBUG OnInitComplete(THREAD_CALL_FAILD) ; return THREAD_CALL_FAILD ; } else { #ifdef _DEBUG printf("taskid 0x%x spawned.\n",m_hTask) ; #endif // _DEBUG } #endif // VXWORKS } // All the sockets and threads are loaded m_bReady = true ; OnInitComplete(OK) ; return OK ; } unsigned long CUdpSocket::recvsrv(void * pt) { CUdpSocket * pthis = (CUdpSocket *)pt ; static char szBuf[4096] ; int iSockAddrSize = sizeof(sockaddr_in) ; static char szIpAddr[16] ; // Receive data form network. // When any data arrive, call OnBeforReceive() and // OnReceive to dispose the data. while (true) { FD_ZERO(&(pthis->m_fdSel)) ; FD_SET((unsigned)pthis->m_sockReceiver, &(pthis->m_fdSel)) ; #ifdef _DEBUG // printf("waiting for incoming message.\n") ; #endif // _DEBUG if (!select(FD_SETSIZE,&(pthis->m_fdSel), NULL,NULL,&(pthis->m_tvDelay))) { #ifdef VXWORKS taskDelay(1) ; #endif // VXWORKS continue ; } memset(szBuf,0,4096) ; memset(&(pthis->m_addrRecv),0, sizeof(sockaddr_in)) ; int iRet=recvfrom (pthis->m_sockReceiver, szBuf,4096,0, (SOCKADDR*)&(pthis->m_addrRecv), &iSockAddrSize ) ; strcpy(szIpAddr,inet_ntoa (pthis->m_addrRecv.sin_addr)) ; if (iRet!=SOCKET_ERROR) { pthis->OnBeforeReceive (iRet,szBuf,&(pthis->m_addrRecv)) ; pthis->OnReceive (iRet,szBuf,&(pthis->m_addrRecv)) ; } } } void CUdpSocket::SetRemoteAddr(const char * targetip,int port) { // Set port and remote host for sender m_addrRemote.sin_port=htons((short)port) ; m_addrRemote.sin_addr.s_addr=inet_addr(targetip) ; } const char * CUdpSocket::GetRemoteIp() { static char szIp[16] ; strcpy(szIp,inet_ntoa(m_addrRemote.sin_addr)) ; return szIp ; } int CUdpSocket::GetRemotePort() { return m_addrRemote.sin_port ; } int CUdpSocket::GetLocalPort() { return m_addrRemote.sin_port ; } STATUS CUdpSocket::Send (int buflen,void * buf,sockaddr_in * addr) { // The simple version for sendto(...) int nBytesSent ; if (!m_bReady) return NOT_INITIALIZED ; if (addr==NULL) addr = &m_addrRemote ; OnBeforeSend(buflen,buf) ; nBytesSent = sendto (m_sockSender,(char *)buf,buflen,0, (SOCKADDR*)addr,sizeof(SOCKADDR) ) ; OnSendComplete(nBytesSent) ; return nBytesSent ; } STATUS CUdpSocket::Recv(int buflen,void * buf, int timeout,sockaddr_in * addr) { int iSockAddrSize = sizeof(sockaddr_in) ; int iRet = NULL ; timeval tv ; // Receive data form network. if (timeout!=0) { FD_ZERO(&(m_fdSel)) ; FD_SET((unsigned)m_sockReceiver,&m_fdSel) ; tv.tv_sec = timeout/1000 ; tv.tv_usec = (timeout%1000)*1000 ; #ifdef _DEBUG printf("waiting for incoming message.\n") ; #endif // _DEBUG if (!select(FD_SETSIZE,&m_fdSel, NULL,NULL,&tv)) return RECV_TIMEOUT ; } memset(buf,0,buflen) ; if (addr==NULL) { memset(&m_addrRecv,0,sizeof(sockaddr_in)) ; addr = &m_addrRecv ; } else { memset(addr,0,sizeof(sockaddr_in)) ; } iRet = recvfrom // Receive data gram (m_sockReceiver, (char *)buf,buflen,0, (SOCKADDR*)addr,&iSockAddrSize ) ; return iRet ; } STATUS CUdpSocket::SetSenderBufferSize(int size) { return setsockopt (m_sockSender,SOL_SOCKET, SO_SNDBUF,(char *)&size,sizeof(int) ) ; } int CUdpSocket::GetSenderBufferSize() { int size,n ; getsockopt (m_sockSender,SOL_SOCKET, SO_SNDBUF,(char *)&size,&n ) ; return size ; } STATUS CUdpSocket::SetReceiverBufferSize(int size) { return setsockopt (m_sockReceiver,SOL_SOCKET, SO_SNDBUF,(char *)&size,sizeof(int) ) ; } int CUdpSocket::GetReceiverBufferSize() { int size,n ; getsockopt (m_sockReceiver,SOL_SOCKET, SO_SNDBUF,(char *)&size,&n ) ; return size ; } int CUdpSocket::GetSenderSocket() { return m_sockSender ; } int CUdpSocket::GetReceiverSocket() { return m_sockReceiver ; } CUdpSocket::~CUdpSocket() { #ifdef WIN32 #ifdef _DEBUG BOOL bThreadTerminated = FALSE ; #endif // _DEBUG if (NULL!=m_sockSender&& INVALID_SOCKET!=m_sockSender) closesocket(m_sockSender) ; if (NULL!=m_sockReceiver&& INVALID_SOCKET!=m_sockReceiver) closesocket(m_sockReceiver) ; WSACleanup() ; // Terminate the recvsrv thread #ifdef _DEBUG bThreadTerminated = TerminateThread ((HANDLE)m_hThread,0) ; CloseHandle(m_hThread) ; if (bThreadTerminated) printf("thread 0x%x terminated.\n",m_hThread) ; #else TerminateThread((HANDLE)m_hThread,0) ; #endif // _DEBUG #endif // _WIN32 #ifdef VXWORKS #ifdef _DEBUG bool bTaskDeleted = false ; #endif // _DEBUG if (NULL!=m_sockSender&& INVALID_SOCKET!=m_sockSender) { shutdown(m_sockSender,2) ; close(m_sockSender) ; } if (NULL!=m_sockReceiver&& INVALID_SOCKET!=m_sockReceiver) { shutdown(m_sockReceiver,2) ; close(m_sockReceiver) ; } #ifdef _DEBUG bTaskDeleted = taskDelete(m_hTask) ; if (bTaskDeleted!=ERROR) printf("task 0x%x deleted.\n",m_hTask) ; #else taskDelete(m_hTask) ; #endif // _DEBUG #endif // VXWORKS } // Our overridable functions. // In the base class "CUdpSocket", the functions do nothing void CUdpSocket::OnInitComplete(STATUS status) { #ifdef _DEBUG printf("OnInitComplete(%d)\n",status) ; #endif } void CUdpSocket::OnBeforeSend(int buflen,void * buf) { #ifdef _DEBUG printf("OnBeforeSend(%d,...)\n",buflen) ; #endif } void CUdpSocket::OnSendComplete(STATUS status) { #ifdef _DEBUG printf("OnSendComplete(%d)\n",status) ; #endif } void CUdpSocket::OnBeforeReceive (int buflen,void * buf,sockaddr_in * addr) { #ifdef _DEBUG printf("OnBeforeReceive(%d,...)\n",buflen) ; #endif } void CUdpSocket::OnReceive (int buflen,void * buf,sockaddr_in * addr) { #ifdef _DEBUG printf("OnReceive(%d,...)\n",buflen) ; #endif } // End of the file