#include <winsock2.h>
#include <windows.h>
#include <stdlib.h>
#include "SockThread.h"
CSockThread* CSockThread::instance = NULL;
CSockThread::CSockThread ()
{
instance = this;
m_hThreadAccept = NULL;
InitializeCriticalSection ( &m_criticalSection );
m_hEndEvent = CreateEvent ( NULL, TRUE, FALSE, NULL );
m_hSendRequestEvent = CreateEvent ( NULL, TRUE, FALSE, NULL );
ResetEvent ( m_hEndEvent );
ResetEvent ( m_hSendRequestEvent );
}
CSockThread::~CSockThread ()
{
SetEvent ( m_hEndEvent );
if(m_hThreadAccept != NULL){
WaitForSingleObject ( m_hThreadAccept, INFINITE );
CloseHandle ( m_hThreadAccept );
}
CloseHandle ( m_hEndEvent );
CloseHandle ( m_hSendRequestEvent );
DeleteCriticalSection ( &m_criticalSection );
}
DWORD WINAPI CSockThread::threadMain ( LPVOID* param )
{
CSockThread* pcst = (CSockThread*)param;
pcst->accept_main ( param );
return 0;
}
void CSockThread::start ()
{
DWORD threadid;
m_hThreadAccept = CreateThread ( NULL, 0, (LPTHREAD_START_ROUTINE)threadMain, this, 0, &threadid );
}
void CSockThread::stop ()
{
SetEvent ( m_hEndEvent );
if(m_hThreadAccept != NULL){
WaitForSingleObject ( m_hThreadAccept, INFINITE );
CloseHandle ( m_hThreadAccept );
m_hThreadAccept = NULL;
}
}
void CSockThread::accept_main ( LPVOID * )
{
HANDLE hAcceptEvent;
WSANETWORKEVENTS wwe;
hAcceptEvent = WSACreateEvent ();
int ret;
SOCKET listensock = createlistensock ( 1234 );
ret = WSAEventSelect ( listensock, hAcceptEvent, FD_ACCEPT );
if(SOCKET_ERROR == ret){
printlog ( LOG_ERR, GetLastError (), L"WSAEventSelectエラー" );
WSACloseEvent ( hAcceptEvent );
return ;
}
while(true){
DWORD dwRet;
HANDLE phs[ 3 ];
phs[ 0 ] = m_hEndEvent;
phs[ 1 ] = hAcceptEvent;
dwRet = WaitForMultipleObjects ( 2, phs, FALSE, INFINITE );
if(dwRet == WAIT_OBJECT_0 + 1){
WSAEnumNetworkEvents ( listensock, hAcceptEvent, &wwe );
if(wwe.lNetworkEvents & FD_ACCEPT){
SOCKET sock = waitaccept ( listensock, NULL );
bIsAccepted = true;
comm_main ( (LPVOID*)&sock );
bIsAccepted = false;
clearSendData ();
}
}
else{
break;
}
}
WSACloseEvent ( hAcceptEvent );
}
void CSockThread::comm_main ( LPVOID * param )
{
SOCKET sock = *( (SOCKET*)param );
bool loopflag = true;
if(sendWaveInfo ( sock ) <= 0){
loopflag = false;
}
while(loopflag){
DWORD dwRet;
HANDLE hevs[ 2 ] = { m_hEndEvent, m_hSendRequestEvent };
dwRet = WaitForMultipleObjects ( 2, hevs, FALSE, INFINITE );
if(dwRet == WAIT_OBJECT_0 + 1){
list<SENDDATA>* sendlist = getSendData ();
if(sendlist == NULL){
continue;
}
list<SENDDATA>::iterator ite;
SENDHEAD head;
for(ite = sendlist->begin(); ite != sendlist->end(); ite++){
if(m_waveFormatEx.wBitsPerSample == 32){
int frame = ( *ite ).len / ( sizeof ( float ) * 2 );
DWORD sendlen = frame * ( sizeof ( WORD ) * 2 );
float* pfloat = (float*)( ( *ite ).buf );
WORD* pword = (WORD*)( ( *ite ).buf );
for(int j = 0; j < frame * 2; j++){
float f = pfloat[ j ] *= 32768.0f;
pword[ j ] = (WORD)f;
}
( *ite ).len = sendlen;
}
head.id = RIFFCC ( 'F*CK' );
head.sentDate.wYear = _byteswap_ushort ( ( *ite ).addedDate.wYear );
head.sentDate.wMonth = _byteswap_ushort ( ( *ite ).addedDate.wMonth );
head.sentDate.wDayOfWeek = _byteswap_ushort ( ( *ite ).addedDate.wDayOfWeek );
head.sentDate.wDay = _byteswap_ushort ( ( *ite ).addedDate.wDay );
head.sentDate.wHour = _byteswap_ushort ( ( *ite ).addedDate.wHour );
head.sentDate.wMinute = _byteswap_ushort ( ( *ite ).addedDate.wMinute );
head.sentDate.wSecond = _byteswap_ushort ( ( *ite ).addedDate.wSecond );
head.sentDate.wMilliseconds = _byteswap_ushort ( ( *ite ).addedDate.wMilliseconds );
head.waveDatLen = _byteswap_ulong ( ( *ite ).len );
if(sock != INVALID_SOCKET){
if(socksend ( sock, (char*)&head, sizeof ( SENDHEAD ), 0 ) < 0){
closesocket ( sock );
sock = INVALID_SOCKET;
break;
}
if(socksend ( sock, (char*)(*ite).buf, ( *ite ).len, 0 ) < 0){
closesocket ( sock );
sock = INVALID_SOCKET;
break;
}
}
delete ( *ite ).buf;
}
delete sendlist;
if(sock == INVALID_SOCKET){
break;
}
}
else{
break;
}
}
}
void CSockThread::setWaveInfo ( WAVEFORMATEX* pw )
{
m_waveFormatEx = *pw;
}
void CSockThread::clearSendData ()
{
if(bIsAccepted == false){
list<SENDDATA>* droplist = NULL;
EnterCriticalSection ( &m_criticalSection );
if(wavdatalist != NULL&&wavdatalist->size () != 0){
droplist = wavdatalist;
wavdatalist = NULL;
}
LeaveCriticalSection ( &m_criticalSection );
if(droplist != NULL){
list<SENDDATA>::iterator ite;
for(ite = droplist->begin (); ite != droplist->end (); ite++){
delete ( *ite ).buf;
}
delete droplist;
}
}
}
void CSockThread::addSendData ( void* wavdata, DWORD len )
{
if(bIsAccepted == false){
clearSendData ();
return;
}
SENDDATA senddata;
GetSystemTime ( &senddata.addedDate );
senddata.len = len;
senddata.buf = new char[ len ];
if(wavdata){
CopyMemory ( senddata.buf, wavdata, len );
}
else{
if(m_waveFormatEx.wBitsPerSample == 8){
FillMemory ( senddata.buf, len, 0x80 );
}
else{
ZeroMemory ( senddata.buf, len );
}
}
EnterCriticalSection ( &m_criticalSection );
if(wavdatalist == NULL){
wavdatalist = new list<SENDDATA> ();
}
wavdatalist->push_back ( senddata );
SetEvent ( m_hSendRequestEvent );
LeaveCriticalSection ( &m_criticalSection );
}
list<SENDDATA>* CSockThread::getSendData ()
{
list<SENDDATA>* retlist = NULL;
EnterCriticalSection ( &m_criticalSection );
ResetEvent ( m_hSendRequestEvent );
retlist = wavdatalist;
wavdatalist = NULL;
LeaveCriticalSection ( &m_criticalSection );
return retlist;
}
int CSockThread::sendWaveInfo ( SOCKET sock ){
struct WAVEINFO{
DWORD id;
WORD wBitsPerSample;
WORD nChannels;
DWORD nSamplesPerSec;
}wi;
wi.id = RIFFCC ( 'f*ck' );
wi.wBitsPerSample = _byteswap_ushort ( m_waveFormatEx.wBitsPerSample == 32 ? 16 : m_waveFormatEx.wBitsPerSample );
wi.nChannels = _byteswap_ushort ( m_waveFormatEx.nChannels );
wi.nSamplesPerSec = _byteswap_ulong ( m_waveFormatEx.nSamplesPerSec );
return socksend ( sock, (char*)&wi, sizeof ( wi ), 0 );
}