以下是接口部分
// .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;
}
浙公网安备 33010602011771号