导航

UDP 封装类

Posted on 2009-03-13 23:54  My Gold  阅读(1205)  评论(0)    收藏  举报

以下是接口部分

// .h 文件

 

#pragma once

class TCustomSocket
{
public:
 virtual int SendBuf(const char* ToIP, unsigned short ToPort, const char* Buf, int BufSize)=0;
 virtual int RecvBuf(char *Buf, int BufSize, char* FromIP, unsigned short &FromPort)=0;
 virtual ~TCustomSocket(void);
};

 

//.cpp 文件

 

#include "TCustomSocket.h"

TCustomSocket::~TCustomSocket()
{

}

 

 

 

以下是实现部分

//.h 文件

#pragma once
#include "tcustomsocket.h"

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <sys/time.h>


typedef void(*TOnDataRead)(TCustomSocket* pSocket);

class TUdpSocket :
 public TCustomSocket
{
public:
 TUdpSocket(void);
 TUdpSocket(const char* szIP, unsigned short Port, int Timeout, bool RecvOnCreated);
 TUdpSocket(const char* szIP, unsigned short Port, int Timeout, bool RecvOnCreated, TOnDataRead onDataRead);
 ~TUdpSocket(void);

//method 方法
public:
 int SendBuf(const char* ToIP, unsigned short ToPort, const char* Buf, int BufSize);
 int RecvBuf(char *Buf, int BufSize, char* FromIP, unsigned short &FromPort);
private:
 void InitLock();
 void UnInitLock();
 void Lock();
 bool TryLock();
 void UnLock();

 static void* ThreadProc(void *arg);

protected:

//property 属性
protected:
private:
 int GetSocketFd();

//varible 变量
private:
 //描述符
 int m_sockfd;
 //...
 struct timeval m_tmval;
 //是否接收数据
 bool m_bStopRecv;
 //是否终止接收线程
 bool m_bExitThread;

 //线程ID
 pthread_t threadid;
 //线程访问控制锁
 pthread_mutex_t mutex;
 //数据接收调用函数
 TOnDataRead OnDataRead;
};

 

//.cpp 文件

#include "TUdpSocket.h"
#include "syhead.h"

#include <pthread.h>


TUdpSocket::TUdpSocket(void)
{
 OnDataRead = NULL;
 m_bExitThread = false;
 threadid = -1;
 m_sockfd = -1;
 m_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
 if (m_sockfd < 0)
 {
  //???
 }
 
 struct sockaddr_in mysockaddr;
 mysockaddr.sin_family = AF_INET;
 mysockaddr.sin_port = htons(0);
 mysockaddr.sin_addr.s_addr = htonl(0);

 bind(m_sockfd, (sockaddr*)&mysockaddr, sizeof(sockaddr));

 fcntl(m_sockfd, F_SETFL, O_ASYNC);

 m_tmval.tv_sec = 0;
 m_tmval.tv_usec = 10*1000;

 InitLock();

}

TUdpSocket::TUdpSocket(const char *szIP, unsigned short Port, int Timeout, bool RecvOnCreated)
{
 OnDataRead = NULL;
 m_bExitThread = false;
 threadid = -1;
 m_sockfd = -1;
 m_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
 if (m_sockfd < 0)
 {
  //???
 }

 int iVal = 1;

 setsockopt(m_sockfd, SOL_SOCKET, SO_REUSEADDR, &iVal, sizeof(iVal));

 fcntl(m_sockfd, F_SETFL, O_ASYNC);

 struct sockaddr_in mysockaddr;
 mysockaddr.sin_family = AF_INET;
 mysockaddr.sin_port = htons(Port);
 mysockaddr.sin_addr.s_addr = 0;

 bind(m_sockfd, (sockaddr*)&mysockaddr, sizeof(sockaddr));

 m_tmval.tv_sec = 0;
 m_tmval.tv_usec = Timeout * 1000;

 m_bStopRecv = false;

 InitLock();

 if (RecvOnCreated)
 {
  pthread_create(&threadid, NULL, ThreadProc, this);
 }
}

TUdpSocket::TUdpSocket(const char *szIP, unsigned short Port, int Timeout, bool RecvOnCreated, TOnDataRead onDataRead)
{
 OnDataRead = NULL;
 m_bExitThread = false;
 threadid = -1;
 m_sockfd = -1;
 m_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
 if (m_sockfd < 0)
 {
  //???
 }

 int iVal = 1;

 setsockopt(m_sockfd, SOL_SOCKET, SO_REUSEADDR, &iVal, sizeof(iVal));

 fcntl(m_sockfd, F_SETFL, O_ASYNC);

 struct sockaddr_in mysockaddr;
 mysockaddr.sin_family = AF_INET;
 mysockaddr.sin_port = htons(Port);
 mysockaddr.sin_addr.s_addr = 0;

 bind(m_sockfd, (sockaddr*)&mysockaddr, sizeof(sockaddr));

 m_tmval.tv_sec = 0;
 m_tmval.tv_usec = Timeout * 1000;

 m_bStopRecv = false;

 InitLock();

 if (RecvOnCreated)
 {
  pthread_create(&threadid, NULL, ThreadProc, this);
 }

 OnDataRead = onDataRead;
}

void *TUdpSocket::ThreadProc(void *arg)
{
 char buf[10240];

 char szFromIP[20];

 unsigned short wFromPort;

 memset(szFromIP, 0, sizeof(szFromIP));

 TUdpSocket *p = (TUdpSocket*)arg;

 fd_set fdset;

 struct timeval tmval = p->m_tmval;

 while (true)
 {
  if (p->m_bExitThread)
  {
   break;
  }

  if (!p->m_bStopRecv)
  {
   FD_ZERO(&fdset);
   FD_SET(p->GetSocketFd(), &fdset);

   int retval = -1;

   retval = select(p->GetSocketFd()+1, &fdset,NULL,NULL, &tmval);

   if (retval > 0)
   {
    if (p->OnDataRead)
    {
     p->OnDataRead(p);
    }
    else
    {
     char buf[10240];
     char FromIP[20];
     unsigned short FromPort;
     p->RecvBuf(buf, sizeof(buf), FromIP, FromPort);
    }
   }
  }

  usleep(50);
 }

 return 0;
}

TUdpSocket::~TUdpSocket(void)
{
 if (threadid > 0)
 {
  cout << "destroy thread: "<< threadid << endl;
  m_bExitThread = true;
 }

 close(m_sockfd);
}

void TUdpSocket::InitLock()
{
 pthread_mutex_init(&mutex, NULL);
}

void TUdpSocket::UnInitLock()
{
 pthread_mutex_destroy(&mutex);
}

void TUdpSocket::Lock()
{
 pthread_mutex_lock(&mutex);
}

void TUdpSocket::UnLock()
{
 pthread_mutex_unlock(&mutex);
}

bool TUdpSocket::TryLock()
{
 pthread_mutex_trylock(&mutex);
}

int TUdpSocket::RecvBuf(char *Buf, int BufSize, char* FromIP, unsigned short &FromPort)
{
 if (m_sockfd <= 0)
 {
  return -1;
 }

 int iRecvLen = 0;

 struct sockaddr_in skaddr;
 socklen_t ilen = sizeof(skaddr);

 Lock();
 iRecvLen = recvfrom(m_sockfd, Buf, BufSize, 0, (sockaddr*)&skaddr, &ilen);
 UnLock();

 strncpy(FromIP, inet_ntoa(skaddr.sin_addr), 16);
 FromPort = ntohs(skaddr.sin_port);

 return iRecvLen;
}

int TUdpSocket::SendBuf(const char* ToIP, unsigned short ToPort, const char* Buf, int BufSize)
{
 int iLen = -1;

 struct sockaddr_in skaddr;

 skaddr.sin_family = AF_INET;
 skaddr.sin_port = htons(ToPort);
 skaddr.sin_addr.s_addr = inet_addr(ToIP);
 
 Lock();
 iLen = sendto(m_sockfd, Buf, BufSize, 0, (sockaddr*)&skaddr, sizeof(skaddr));
 UnLock();

 return iLen;
}

int TUdpSocket::GetSocketFd()
{
 return m_sockfd;
}