Your solution sounds reasonable except for one point. You mention that you will create a thread to connect to each machine, then a sub-thread to manage sending, receiving, and parsing. I dont understand why you need to create a sub-thread. You should be able to handle everything in the connection thread. Also consider that 1 thread per connection may not scale well, if this application has to deal with a larger number of machines, a thread per machine should be avoided.
It may even be possible to achieve this with a simple thread pool instead of 1 thread per connection, which wont scale well. You could consider creating tasks that get put on a worker queue every 5 seconds, and the pool of threads would connect, read, disconnect, parse, and process. Assuming this is TCP/IP you probably shouldnt keep the connection open, but rather connect/disconnect for each read, similar to HTTP.
Here is a vc++ thread pool related question. And here is some more related info.
Another alternative could be to use libevent for the socket communication. As for the parsing, there are also other libraries that can be used like Apache Thrift or JSon, all of which are open source. The down side to these parsing libraries is that you may have to also modify the dialysis machines which may not be an option. If you can use something like Thrift, you can get everything from one library: socket comm and parsing.
Here is some code for the simple case of 1 thread per connection:
class ThreadInfo
{
public:
ThreadInfo(const string &ipAddress, uint16_t port) : ipAddress_(ipAddress), port_(port) {}
string getIpAddress() {return ipAddress_;}
uint16_t getPort() {return port_;}
string getRecvBuffer() {return recvBuffer_;}
private:
string ipAddress_;
uint16_t port_;
string recvBuffer_;
};
void *threadEntryPoint(void *userData)
{
ThreadInfo *threadInfo = (ThreadInfo*) userData;
// You need to decide if you want to keep the connection open while sleeping
// or open and close it for each transaction. Change code here accordingly.
// Create socket with threadInfo->getIpAddress() and threadInfo->getPort()
// while(1)
// Send request to each machine
// Get response from each machine and store in threadInfo->getRecvBuffer()
// The buffer could also be a local var in this function, decide accordingly
// parse data accordingly
// sleep 5 seconds
}
uint16_t getPort(int machineNum) { return 3456; }
string getIpAddress(int machineNum) { return string("192.168.1.2"); }
int main(int argc, char **argv)
{
// 3 items that we need, and that you will have to plugin accordingly:
// 1) Num threads, assuming 100 for now
// 2) IP address of each external machine, implement getIpAddress() accordingly
// 3) port of each machine, implement getPort() accordingly
int numThreads(100);
list<pthread_t> threadIdList;
for(int i = 0; i < numThreads; ++i)
{
pthread_t threadId;
ThreadInfo *threadInfo = new ThreadInfo(getIpAddress(i), getPort(i));
pthread_create(&threadId, NULL, threadEntryPoint, threadInfo);
threadIdList.push_back(threadId);
}
// Wait for the threads to finish
std::list<pthread_t>::iterator iter = threadIdList.begin();
while(iter != threadIdList.end())
{
pthread_t threadId = *iter++;
pthread_join(threadId, NULL);
}
}