Creating Multiple TCP Socket Connections

In one of my parsing programs, I have to do the following (in C, C ++, VC ++): -

I need to connect 100 machines (dialysis machines) through socket programming. Send a request for each car and get a response from the car and the data that I receive from the car. I will need to parse this data and write the values โ€‹โ€‹in a file. I need to send a request to every machine every 5 seconds.

So, in order to accomplish the above task, I think we need to do this as: -

I will read the ip and port of each machine from the database, make a stream to connect to each machine, and in each stream an additional stream (a child stream) will be created that will send and receive and analyze data from the machine every 5 seconds (and write values โ€‹โ€‹in the txt file). My parsing function will be distributed.

This is a possible solution. Please help me. Tnax in advance.

+4
source share
3 answers

Your decision seems reasonable, except for one point. You mentioned that you will create a thread to connect to each machine, and then a sub-thread to control sending, receiving, and analysis. I do not understand why you need to create a sub thread. You should be able to handle everything in the connection thread. Also note that 1 thread per connection may not scale well, if this application has to deal with a large number of machines, you should avoid threading to a machine.

It is even possible to achieve this with a simple thread pool instead of 1 thread for each connection that will not scale well. You can consider creating tasks that will be placed in the work queue every 5 seconds, and the thread pool will connect, read, disconnect, analyze and process. Assuming this is TCP / IP, you probably shouldn't keep the connection open, but rather connect / disconnect for each read, similar to HTTP.

Here is a question related to vC ++ thread pool. And here is another related information.

Another alternative might be to use libevent to communicate a socket. Regarding parsing, there are other libraries that can be used as Apache Thrift or JSon , all of which are open source. The downside of these parsing libraries is that you may also need to modify dialysis machines, which may not be an alternative. If you can use something like Thrift, you can get everything from one library: socket comm and parsing.

Here is a sample code for a simple case of 1 thread for each 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); } } 
+4
source

For 100 machines, polling every 5 seconds, one thread per machine is reasonable - threads will block in sleep mode (5000) for most of the time and block in disk I / O or disk I / O for most of the rest of the time. For this type of download (or even fivefold download) I donโ€™t see the need to use asynchronous I / O or thread pools - why is it difficult because it is not necessary?

As @Brady pointed out, I donโ€™t understand why you need more than one thread for each connection, considering that this requirement is fulfilled as you send a message - just polling every 5 seconds and writing the responses to a text file.

I assume (hopefully) :) that the 5 second interval is not a real-time critical requirement, and that dialysis machines will continue to work normally if the period is sometimes 6 seconds due to some temporary software or network latency. I am not a hematologist / nephrologist, but I would be surprised if any dialysis machine could make any significant changes to the general treatment (which takes several hours) if the survey / instruction was sometimes delayed for an extra second.

Change - re. โ€œa parsing function and writing data to a file function are common to all streamsโ€ - this should be good, provided that a different text file is used for each computer. If a single log file is recorded in the log, this is more of a problem - each log entry should be queued for one log, which one writes to the log file. Using an existing, proven registration platform that already supports this functionality will be the easiest solution.

+1
source

If you use the boost :: asio infrastructure for network and disk I / O, you are likely to avoid far fewer threads than one per machine to process.

In addition, it has a good high-level socket programming interface.

0
source

Source: https://habr.com/ru/post/1434770/


All Articles