Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
63c4d67e3This file is pinned to the selected release. Download the original to open it in your design tool.
#include "PassiveSocket.h" // Include header for active socket object definition
#include <stdio.h>
#include "../../CommonInterfaces/CommonGUIHelperInterface.h"
#include "Bullet3Common/b3CommandLineArgs.h"
#ifdef NO_SHARED_MEMORY
#include "PhysicsServerCommandProcessor.h"
typedef PhysicsServerCommandProcessor MyCommandProcessor;
#else
#include "SharedMemoryCommandProcessor.h"
typedef SharedMemoryCommandProcessor MyCommandProcessor;
#endif //NO_SHARED_MEMORY
#include "SharedMemoryCommands.h"
#include "Bullet3Common/b3AlignedObjectArray.h"
#include "PhysicsServerCommandProcessor.h"
#include "../Utils/b3Clock.h"
bool gVerboseNetworkMessagesServer = true;
void MySerializeInt(unsigned int sz, unsigned char* output)
{
unsigned int tmp = sz;
output[0] = tmp & 255;
tmp = tmp >> 8;
output[1] = tmp & 255;
tmp = tmp >> 8;
output[2] = tmp & 255;
tmp = tmp >> 8;
output[3] = tmp & 255;
}
int main(int argc, char* argv[])
{
b3CommandLineArgs parseArgs(argc, argv);
b3Clock clock;
double timeOutInSeconds = 10;
DummyGUIHelper guiHelper;
MyCommandProcessor* sm = new MyCommandProcessor;
sm->setGuiHelper(&guiHelper);
int port = 6667;
parseArgs.GetCmdLineArgument("port", port);
gVerboseNetworkMessagesServer = parseArgs.CheckCmdLineFlag("verbose");
#ifndef NO_SHARED_MEMORY
int key = 0;
if (parseArgs.GetCmdLineArgument("sharedMemoryKey", key))
{
sm->setSharedMemoryKey(key);
}
#endif //NO_SHARED_MEMORY
bool isPhysicsClientConnected = sm->connect();
bool exitRequested = false;
if (isPhysicsClientConnected)
{
printf("Starting TCP server using port %d\n", port);
CPassiveSocket socket;
CActiveSocket* pClient = NULL;
//--------------------------------------------------------------------------
// Initialize our socket object
//--------------------------------------------------------------------------
socket.Initialize();
socket.Listen("localhost", port);
//socket.SetBlocking();
int curNumErr = 0;
while (!exitRequested)
{
b3Clock::usleep(0);
if ((pClient = socket.Accept()) != NULL)
{
b3AlignedObjectArray<char> bytesReceived;
int clientPort = socket.GetClientPort();
printf("connected from %s:%d\n", socket.GetClientAddr(), clientPort);
if (pClient->Receive(4))
{
int clientKey = *(int*)pClient->GetData();
if (clientKey == SHARED_MEMORY_MAGIC_NUMBER)
{
printf("Client version OK %d\n", clientKey);
}
else
{
printf("Server version (%d) mismatches Client Version (%d)\n", SHARED_MEMORY_MAGIC_NUMBER, clientKey);
continue;
}
}
//----------------------------------------------------------------------
// Receive request from the client.
//----------------------------------------------------------------------
while (1)
{
//printf("try receive\n");
bool receivedData = false;
int maxLen = 4 + sizeof(SharedMemoryStatus) + SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE;
if (pClient->Receive(maxLen))
{
//heuristic to detect disconnected clients
CSimpleSocket::CSocketError err = pClient->GetSocketError();
if (err != CSimpleSocket::SocketSuccess || !pClient->IsSocketValid())
{
b3Clock::usleep(100);
curNumErr++;
if (curNumErr > 100)
{
printf("TCP Connection error = %d, curNumErr = %d\n", (int)err, curNumErr);
break;
}
}
curNumErr = 0;
char* msg2 = (char*)pClient->GetData();
int numBytesRec2 = pClient->GetBytesReceived();
int curSize = bytesReceived.size();
bytesReceived.resize(bytesReceived.size() + numBytesRec2);
for (int i = 0; i < numBytesRec2; i++)
{
bytesReceived[curSize + i] = msg2[i];
}
if (bytesReceived.size() >= 4)
{
int numBytesRec = bytesReceived.size();
if (numBytesRec >= 10)
{
if (strncmp(&bytesReceived[0], "disconnect", 10) == 0)
{
printf("Disconnect request received\n");
bytesReceived.clear();
break;
}
if (strncmp(&bytesReceived[0], "terminateserver", 10) == 0)
{
printf("Terminate server request received\n");
exitRequested = true;
bytesReceived.clear();
break;
}
}
if (gVerboseNetworkMessagesServer)
{
printf("received message length [%d]\n", numBytesRec);
}
receivedData = true;
SharedMemoryCommand cmd;
SharedMemoryCommand* cmdPtr = 0;
int type = *(int*)&bytesReceived[0];
//performance test
if (numBytesRec == sizeof(int))
{
cmdPtr = &cmd;
cmd.m_type = *(int*)&bytesReceived[0];
}
else
{
if (numBytesRec == sizeof(SharedMemoryCommand))
{
cmdPtr = (SharedMemoryCommand*)&bytesReceived[0];
}
else
{
if (numBytesRec == 36)
{
cmdPtr = &cmd;
memcpy(&cmd, &bytesReceived[0], numBytesRec);
}
}
}
if (cmdPtr)
{
SharedMemoryStatus serverStatus;
b3AlignedObjectArray<char> buffer;
buffer.resize(SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE);
bool hasStatus = sm->processCommand(*cmdPtr, serverStatus, &buffer[0], buffer.size());
double startTimeSeconds = clock.getTimeInSeconds();
double curTimeSeconds = clock.getTimeInSeconds();
while ((!hasStatus) && ((curTimeSeconds - startTimeSeconds) < timeOutInSeconds))
{
hasStatus = sm->receiveStatus(serverStatus, &buffer[0], buffer.size());
curTimeSeconds = clock.getTimeInSeconds();
}
if (gVerboseNetworkMessagesServer)
{
//printf("buffer.size = %d\n", buffer.size());
printf("serverStatus.m_numDataStreamBytes = %d\n", serverStatus.m_numDataStreamBytes);
}
if (hasStatus)
{
b3AlignedObjectArray<unsigned char> packetData;
unsigned char* statBytes = (unsigned char*)&serverStatus;
if (cmdPtr->m_type == CMD_STEP_FORWARD_SIMULATION)
{
packetData.resize(4 + sizeof(int));
int sz = packetData.size();
int curPos = 0;
MySerializeInt(sz, &packetData[curPos]);
curPos += 4;
for (int i = 0; i < sizeof(int); i++)
{
packetData[i + curPos] = statBytes[i];
}
curPos += sizeof(int);
pClient->Send(&packetData[0], packetData.size());
}
else
{
if (cmdPtr->m_type == CMD_REQUEST_VR_EVENTS_DATA)
{
int headerSize = 16 + 5 * sizeof(int) + sizeof(smUint64_t) + sizeof(char*) + sizeof(b3VRControllerEvent) * serverStatus.m_sendVREvents.m_numVRControllerEvents;
packetData.resize(4 + headerSize);
int sz = packetData.size();
int curPos = 0;
MySerializeInt(sz, &packetData[curPos]);
curPos += 4;
for (int i = 0; i < headerSize; i++)
{
packetData[i + curPos] = statBytes[i];
}
curPos += headerSize;
pClient->Send(&packetData[0], packetData.size());
}
else
{
//create packetData with [int packetSizeInBytes, status, streamBytes)
packetData.resize(4 + sizeof(SharedMemoryStatus) + serverStatus.m_numDataStreamBytes);
int sz = packetData.size();
int curPos = 0;
if (gVerboseNetworkMessagesServer)
{
//printf("buffer.size = %d\n", buffer.size());
printf("serverStatus packed size = %d\n", sz);
}
MySerializeInt(sz, &packetData[curPos]);
curPos += 4;
for (int i = 0; i < sizeof(SharedMemoryStatus); i++)
{
packetData[i + curPos] = statBytes[i];
}
curPos += sizeof(SharedMemoryStatus);
for (int i = 0; i < serverStatus.m_numDataStreamBytes; i++)
{
packetData[i + curPos] = buffer[i];
}
pClient->Send(&packetData[0], packetData.size());
}
}
}
bytesReceived.clear();
}
else
{
//likely an incomplete packet, let's append more bytes
//printf("received packet with unknown contents\n");
}
}
}
if (!receivedData)
{
//printf("Didn't receive data.\n");
}
}
printf("Disconnecting client.\n");
pClient->Close();
delete pClient;
}
}
socket.Close();
socket.Shutdown(CSimpleSocket::Both);
}
else
{
printf("Error: cannot connect to shared memory physics server.");
}
delete sm;
return 0;
}