#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 );
}