OK, so my corresponding code (UDP):
I have a class for the network stuff, it contains:
(.h)
class asd_API asd {
public:
asd(){};
~asd(){};
void Connect(char *toIP);
void ConnectUDP(char *toIP);
private:
static int InitializeUDP();
static void UDPResponseThread();
static int UDPStartSocket();
static int UDPStartServerListening(int serverSocket2);
static void UDPReceiveThread();
static void EndServer(int socket);
static void DulpicateSocket();
};
(.cpp)
#define g_szPipeName "\\\\.\\Pipe\\CSEPPPipe"
#define PIPE_SIZE sizeof(WSAPROTOCOL_INFO)
#define MAX_MESSAGE_SIZE 100
int nBytes;
char buffer[MAX_MESSAGE_SIZE];
char myID[MAX_MESSAGE_SIZE-3] = "id=none";
u_long iMode=1; //1 -non-blocking
int p_int;
int n_Type;
int serverSocket;
int clientSocket;
int thread;
char *n_IP = "127.0.0.1";
unsigned short n_Port = 7700;
bool n_RunThread = true;
bool n_Protocol = 0;
HANDLE AcceptOrReceiveThread;
HANDLE ResponseThread;
HANDLE DuplicateThread;
HANDLE IdentThread;
HANDLE Hmutex;
HANDLE Imutex;
struct sockaddr_in server;
struct sockaddr_in si_other;
struct hostent *hostEntity;
int silen=sizeof(si_other);
int asd::InitializeUDP()
{
serverSocket = UDPStartSocket();
DuplicateThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)DulpicateSocket, NULL, 0, NULL);
if (DuplicateThread == NULL)
{
EndServer(serverSocket);
return 1;
}
SetThreadPriority(AcceptOrReceiveThread,THREAD_PRIORITY_BELOW_NORMAL);
if (serverSocket == -1)
{
return 1;
}
Hmutex = CreateMutex(NULL, false, NULL);// Create the mutex
if (Hmutex == NULL)
{
EndServer(serverSocket);
return 1;
}
Imutex = CreateMutex(NULL, false, NULL);// Create the mutex
if (Imutex == NULL)
{
EndServer(serverSocket);
return 1;
}
ResponseThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)UDPResponseThread, NULL, 0, NULL);
if (ResponseThread == NULL)
{
EndServer(serverSocket);
return 1;
}
SetThreadPriority(ResponseThread,THREAD_PRIORITY_BELOW_NORMAL);
AcceptOrReceiveThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)UDPReceiveThread, NULL, 0,NULL);
if (AcceptOrReceiveThread == NULL)
{
EndServer(serverSocket);
return 1;
}
SetThreadPriority(AcceptOrReceiveThread,THREAD_PRIORITY_BELOW_NORMAL);
Sleep(100);// Let the threads start up;
return 0;
}
int asd::UDPStartSocket()
{
int error;
WSAData wsaData;
if ((error = WSAStartup(MAKEWORD(2, 2), &wsaData)) == SOCKET_ERROR)
{
return -1;
}
int mySocket;
mySocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (mySocket == SOCKET_ERROR)
{
return -1;
}
switch (n_Type)
{
case 0:
UDPStartServerListening(mySocket);
break;
default:
ioctlsocket(mySocket,FIONBIO,&iMode); // in UDPStartServerListening also.
break;
}
return mySocket;
}
int asd::UDPStartServerListening(int serverSocket2)
{
server.sin_family = AF_INET;
server.sin_port = htons(n_Port);
server.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(serverSocket2, (sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)
{
int error = WSAGetLastError();
if (error == 10048) //already in use
{
DulpicateSocket();
}
else
{
closesocket(serverSocket2);
return -1;
}
}
else
ioctlsocket(serverSocket2,FIONBIO,&iMode);
return 0;
}
void asd::DulpicateSocket()
{
switch (n_Type)
{
case 0:
HANDLE hPipe;
hPipe = CreateNamedPipe(
g_szPipeName, // pipe name
PIPE_ACCESS_DUPLEX, // read/write access
PIPE_TYPE_MESSAGE | // message type pipe
PIPE_READMODE_MESSAGE | // message-read mode
PIPE_WAIT, // blocking mode
PIPE_UNLIMITED_INSTANCES, // max. instances
PIPE_SIZE, // output buffer size
PIPE_SIZE, // input buffer size
NMPWAIT_USE_DEFAULT_WAIT, // client time-out
NULL); // default security attribute
if (INVALID_HANDLE_VALUE == hPipe)
{
_tprintf( TEXT("Could not create pipe. GLE=%d\n"), GetLastError() );
}
if (GetLastError() == 183)
{
hPipe = CreateFile(
g_szPipeName, // pipe name
GENERIC_READ | // read and write access
GENERIC_WRITE,
0, // no sharing
NULL, // default security attributes
OPEN_EXISTING, // opens existing pipe
0, // default attributes
NULL); // no template file
char szBuffer[10];
DWORD cbBytes;
sprintf(szBuffer, "%d", GetCurrentProcessId());
WriteFile(
hPipe,
szBuffer,
sizeof(szBuffer),
&cbBytes,
NULL
);
bool van = 1;
for(;;)
{
van = ReadFile(
hPipe, // pipe handle
&protocolinf, // buffer to receive reply
sizeof(WSAPROTOCOL_INFO), // size of buffer
&cbBytes, // number of bytes read
NULL); // not overlapped
if(van == 0)
break;
Sleep(1);
}
serverSocket = WSASocket(protocolinf.iAddressFamily, protocolinf.iSocketType, protocolinf.iProtocol, &protocolinf, 0, NULL);
}
else
{
for(;;) // for multiple instances
{
ConnectNamedPipe(hPipe,NULL); //wait for client to connect to pipe
char szBuffer[10];
DWORD cbBytes;
DWORD rBytes;
ReadFile(
hPipe, // pipe handle
szBuffer, // buffer to receive reply
sizeof(szBuffer), // size of buffer
&cbBytes, // number of bytes read
NULL); // not overlapped
DWORD outBytes = atoi(szBuffer);
WSADuplicateSocket(serverSocket,outBytes,&protocolinf);
WriteFile(
hPipe,
&protocolinf,
sizeof(WSAPROTOCOL_INFO),
&cbBytes,
NULL
);
FlushFileBuffers(hPipe);
DisconnectNamedPipe(hPipe);
Sleep(1);
}
CloseHandle(hPipe);
}
break;//switch
default:
break;
}//switch
}
void asd::UDPReceiveThread()
{
bool exists = false;
for (;;)
{
WaitForSingleObject(Hmutex, INFINITE); // Lock the mutex for UDPTalking
nBytes = recvfrom(serverSocket, buffer, MAX_MESSAGE_SIZE, 0, (SOCKADDR *)&si_other, (int *) &silen); // error 10038 when an instace of this already running.
if (nBytes == SOCKET_ERROR)
{
int error = WSAGetLastError();
if (error == 10057 || error == 10054 || error == 10014)
{
}
else if (error == 10035)
{
}
else
{
std::cout<< "----------------------->" << error << "\n";
Sleep(1000);// only for testing
}
}
else
{
...
}
buffer[0] = '\0';
ReleaseMutex(Hmutex);
Sleep(1);
}
UDPClients.RemoveAll();
}