HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Multithreaded Socket code to connect to 100 different machines

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
connectdifferent100machinescodesocketmultithreaded

Problem

This is my socket.cpp

#pragma hdrstop

#include "MySocketClient.h"

MySocketClient::MySocketClient() throw(SocketException){
    WSAData data;
    InitializeCriticalSection(§_);
    if(WSAStartup(MAKEWORD(2,2),&data)!=0){
        throw SocketException("Cant load WinSock library");
    }
    connected_=false;
}
//-----------------------------------------------------------------------------

MySocketClient::~MySocketClient(){
    WSACleanup();
}
//-----------------------------------------------------------------------------

void MySocketClient::receive(void){
    char recBuf[1024];
    while(1){
        EnterCriticalSection(§_);
        memset(recBuf,0,1024);
        int recLen=recv(sock_,recBuf,1024,0);
        if(recLen==0){
            onDisconnect(sock_);
            connected_=false;
            break;
        }else if(recLenh_addr_list[0];
    if(connect(sock_,(sockaddr*)&addr_,sizeof(sockaddr))==SOCKET_ERROR){
        throw SocketException("Connect Error");
    }
    DWORD dwThreadId;
    threadHandle_=CreateThread(NULL,0,startReceive,this,0,&dwThreadId);
    if(threadHandle_==NULL){
        connected_=false;
        shutdown(sock_,SD_BOTH);
        closesocket(sock_);
        throw SocketException("Receive thread create error");
    }
    connected_=true;
    onConnect(sock_);
}
//------------------------------------------------------------------------------

void MySocketClient::Disconnect(void){
    TerminateThread(threadHandle_,0);
    shutdown(sock_,SD_BOTH);
    closesocket(sock_);
}

        //Virtual functions
void MySocketClient::onReceive(SOCKET sock,char *recBuf,int recLen) throw(SocketException){
}

void MySocketClient::onDisconnect(SOCKET sock){
}

void MySocketClient::onConnectionError(SOCKET sock){
}

void MySocketClient::onSendData(char *sendBuf,int sendLen){

}

void MySocketClient::onConnect(SOCKET sock){
}
#pragma package(smart_init)


This is mysocket.h

```
//----------------------------------------------------------------------

Solution

It could be that at 100 connections you won't notice, but you should be aware that the 1-thread-per-connection model does not scale well and is not in line with the current state of the art. See what is written about the c10k problem.

With a thread-per-connection approach you will have high memory overhead from each thread's stack, and you will spend a lot of time context switching.

What scalable network code does these days is:

-
On Unix: Use epoll (Linux), kqueue (*BSD) or equivalents with non-blocking sockets. The model here is that you ask the kernel to block until some file descriptor is ready for I/O. It informs you which fd is ready and you can issue the non-blocking read or write.

-
On Windows: Issue your I/O with "overlapped" I/O, and use I/O completion ports or APC to be notified when the I/O is finished.

In both of these models the ultimate goal is to not spend time waiting for synchronous I/O, such as a blocking read or write to the socket. This allows you to process multiple requests without needing multiple threads.

Context

StackExchange Code Review Q#15901, answer score: 4

Revisions (0)

No revisions yet.