Constructor of a socket class to solve the slow down by socket in loop.

Hi Experts,

I add a simple socket sending in a loop. The socket slow down the loop quite a lot.
The code for socket is as below.
It is said the slow down is caused by calling WSAStartup, socket(), connect(), WSACleanup() again and again.
And the suggestion is to constructor of a socket class.

Since I am newbie in c++, may you give me the detail instruction how to constructor of a socket class?
Thanks a lot for your help.

Regards,

Turbot

   // Initialize Winsock.
          WSADATA wsaData;
          int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
          if ( iResult != NO_ERROR )
               printf("Error at WSAStartup()\n");

          // Create a socket.
          SOCKET m_socket;
          m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
     
          if ( m_socket == INVALID_SOCKET ) {
               printf( "Error at socket(): %ld\n", WSAGetLastError() );
               WSACleanup();
               //return;
               }
          else{
               // Connect to a server.
               sockaddr_in clientService;
     
               clientService.sin_family = AF_INET;
               clientService.sin_addr.s_addr = inet_addr( IP_ADDRESS_PQHUB );
               clientService.sin_port = htons( PORT_PQHUB );

               if ( connect( m_socket, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR) {
                    printf( "Failed to connect.\n" );
                    WSACleanup();
                    //return;
                    }
               else {//connection is successful                    
                    bytesSent = send( m_socket, sendbuf, strlen(sendbuf), 0 );
                    printf( "Bytes Sent: %ld, %s \n", bytesSent, sendbuf );
                    WSACleanup();
                    }
               }
turbot_yuAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

hemakumarCommented:
it is not required to connect to the server everytime write this outside the loop. and call send in the loop.when the loop comes out call WSACleanUp();

  // Initialize Winsock.
          WSADATA wsaData;
          int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
          if ( iResult != NO_ERROR )
               printf("Error at WSAStartup()\n");

          // Create a socket.
          SOCKET m_socket;
          m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
     
          if ( m_socket == INVALID_SOCKET ) {
               printf( "Error at socket(): %ld\n", WSAGetLastError() );
               WSACleanup();
               //return;
               }
          else{
               // Connect to a server.
               sockaddr_in clientService;
     
               clientService.sin_family = AF_INET;
               clientService.sin_addr.s_addr = inet_addr( IP_ADDRESS_PQHUB );
               clientService.sin_port = htons( PORT_PQHUB );

               if ( connect( m_socket, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR) {
                    printf( "Failed to connect.\n" );
                    WSACleanup();
                    //return;
                    }

             }


If u want to use C++ classes in MFC consider CSocket  class.
 or ur own class by name CMYSocket.

class CMYSocket
{

private:
      CMYSocket (const CMYSocket & rSrc);    // no implementation
      void operator=(const CMYSocket & rSrc);  // no implementation

// Construction
public:
      CMYSocket ();
      BOOL Create(UINT nSocketPort = 0, int nSocketType=SOCK_STREAM,
            long lEvent = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE,
            LPCTSTR lpszSocketAddress = NULL);

// Attributes
public:
      SOCKET m_hSocket;

      operator SOCKET() const;
      

      BOOL GetPeerName(CString& rPeerAddress, UINT& rPeerPort);
      BOOL GetPeerName(SOCKADDR* lpSockAddr, int* lpSockAddrLen);

      BOOL GetSockName(CString& rSocketAddress, UINT& rSocketPort);
      BOOL GetSockName(SOCKADDR* lpSockAddr, int* lpSockAddrLen);

      BOOL SetSockOpt(int nOptionName, const void* lpOptionValue,
            int nOptionLen, int nLevel = SOL_SOCKET);
      BOOL GetSockOpt(int nOptionName, void* lpOptionValue,
            int* lpOptionLen, int nLevel = SOL_SOCKET);

// Operations
public:

      virtual BOOL Accept(CMYSocket & rConnectedSocket,
            SOCKADDR* lpSockAddr = NULL, int* lpSockAddrLen = NULL);

      BOOL Bind(UINT nSocketPort, LPCTSTR lpszSocketAddress = NULL);
      BOOL Bind (const SOCKADDR* lpSockAddr, int nSockAddrLen);

      virtual void Close();

      BOOL Connect(LPCTSTR lpszHostAddress, UINT nHostPort);
      BOOL Connect(const SOCKADDR* lpSockAddr, int nSockAddrLen);

      BOOL IOCtl(long lCommand, DWORD* lpArgument);

      BOOL Listen(int nConnectionBacklog=5);

      virtual int Receive(void* lpBuf, int nBufLen, int nFlags = 0);

      int ReceiveFrom(void* lpBuf, int nBufLen,
            CString& rSocketAddress, UINT& rSocketPort, int nFlags = 0);
      int ReceiveFrom(void* lpBuf, int nBufLen,
            SOCKADDR* lpSockAddr, int* lpSockAddrLen, int nFlags = 0);

      enum { receives = 0, sends = 1, both = 2 };
      BOOL ShutDown(int nHow = sends);

      virtual int Send(const void* lpBuf, int nBufLen, int nFlags = 0);

      int SendTo(const void* lpBuf, int nBufLen,
            UINT nHostPort, LPCTSTR lpszHostAddress = NULL, int nFlags = 0);
      int SendTo(const void* lpBuf, int nBufLen,
            const SOCKADDR* lpSockAddr, int nSockAddrLen, int nFlags = 0);

      BOOL AsyncSelect(long lEvent =
            FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE);

// Overridable callbacks
protected:
      virtual void OnReceive(int nErrorCode);
      virtual void OnSend(int nErrorCode);
      virtual void OnOutOfBandData(int nErrorCode);
      virtual void OnAccept(int nErrorCode);
      virtual void OnConnect(int nErrorCode);
      virtual void OnClose(int nErrorCode);

// Implementation
public:
      virtual ~CMYSocket ();

      static void PASCAL DoCallBack(WPARAM wParam, LPARAM lParam);

      BOOL Socket(int nSocketType=SOCK_STREAM, long lEvent =
            FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE,
            int nProtocolType = 0, int nAddressFormat = PF_INET);


};



















Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
turbot_yuAuthor Commented:
Hi hemakumar,

My loop is belong to a thread in ulWF, there are total 3 thread:
void ulSetup(LPVOID pParam);
void ulES(LPVOID pParam);
void ulWF(LPVOID pParam);

called by:
      _beginthread(ulES, 0, strP);
      Sleep(1000);
      _beginthread(ulWF, 0, strP);
      Sleep(1000);
      _beginthread(ulSetup, 0, strP);

Will it be affected?

The code for ulWF is as below, the calling for socket is in the ending.

Thanks,

Turbot
turbot_yuAuthor Commented:
void ulWF(LPVOID pParam)
{
      UploadParams* pstrP=(UploadParams*)pParam;
      CString instid, sitename, recname;
      int iLoop, iChange;

      iLoop=pstrP->iLoop;
      instid=pstrP->instid;
      sitename=pstrP->sitename;
      recname=pstrP->recname;

      SQLHSTMT hStmt01;
      SQLHSTMT hstmt01;
      SQLCHAR  SqlStmt01[SQL_STMT_LEN];
      SQLCHAR  sqlstmt01[SQL_STMT_LEN];
      RETCODE       RetCode01;
      RETCODE       retcode01;
      SQLINTEGER DataLen;                              //Temporary variable


//      int bytesSent;
//      int bytesRecv = SOCKET_ERROR;
//      char sendbuf[32]; strcpy(sendbuf,"");
      CString sendbuf;                              //string to send to pqhub


      /************************************************************/
      DataStruct dbSession;            //for DB connection

      //connect to PQMS Oracle and PML Sybase
      char defServerName[10];
      strcpy(defServerName, ADM_ORACLE);
      dbSession = OpenDatabase(defServerName);
      int iConnLoop=0;
      while( (dbSession.connORA && dbSession.connPML) == FALSE)
      {
            iConnLoop++;
            if( dbSession.connORA == FALSE )
                  printf("Fail to connect to PQMS Oracle database.\n");
            if( dbSession.connPML == FALSE )
                  printf("Fail to connect to PML Sybase database.\n");

            dbSession.Clear();
            if(iConnLoop<5)
            {
                  Sleep(10000);
                  dbSession = OpenDatabase(defServerName);
            }
            else
                  ExitProcess(1);
      }
      /************************************************************/

      CString StartTime;
      char Timestamp[30];
      char pml_eventdate[30];
      char pml_eventdata[8000];
      CString strEventdata;

      printf("Start Upload SSV1 \n");

      //Upload SSV1
      strcpy(Timestamp, "1900-01-02 00:00:00.000000");
      strcpy(pml_eventdate, "");
      strcpy(pml_eventdata, "");      //8000>7240=2*3620(PML BLOB size)
      strEventdata.Empty();

      SQLAllocHandle(SQL_HANDLE_STMT, dbSession.hDbc, &hStmt01);
      lstrcpy( (char *) SqlStmt01, "SELECT v1ss_t FROM instance WHERE instid=");
      lstrcat( (char *) SqlStmt01, instid);
      lstrcat( (char *) SqlStmt01, ";");
      SQLExecDirect(hStmt01, SqlStmt01, lstrlen((char *)SqlStmt01));
      SQLBindCol( hStmt01,1,SQL_C_CHAR,Timestamp,sizeof(Timestamp), &DataLen);
      RetCode01 = SQLFetch( hStmt01 );
      SQLFreeHandle(SQL_HANDLE_STMT, hStmt01);

      StartTime = GetStartTime(Timestamp, OFFSET);

      SQLAllocHandle(SQL_HANDLE_STMT, dbSession.hdbc, &hstmt01);
      lstrcpy( (char *) sqlstmt01, "SELECT timestamp, v1 FROM ");
      lstrcat( (char *) sqlstmt01, GetSSV1ViewName(sitename, recname));
      lstrcat( (char *) sqlstmt01, " WHERE v1 IS NOT NULL");
      lstrcat( (char *) sqlstmt01, " AND timestamp>\'");
      lstrcat( (char *) sqlstmt01, StartTime);
      lstrcat( (char *) sqlstmt01, "\' ORDER BY timestamp;");

      SQLExecDirect(hstmt01, sqlstmt01, lstrlen((char *)sqlstmt01));
      SQLBindCol( hstmt01,1,SQL_C_CHAR,pml_eventdate,sizeof(pml_eventdate), &DataLen);
      SQLBindCol( hstmt01,2,SQL_C_CHAR,pml_eventdata,sizeof(pml_eventdata), &DataLen);
      retcode01 = SQLFetch( hstmt01 );

      printf("Pml_eventdate is %s. \n", pml_eventdate);

      iChange=0;
      if( retcode01 == SQL_SUCCESS || retcode01 == SQL_SUCCESS_WITH_INFO ) {
            iChange=1;
            printf("iChange for V1ss is %d \n",iChange);
      }
      while ( retcode01 == SQL_SUCCESS || retcode01 == SQL_SUCCESS_WITH_INFO )
      {      //upload data
            char pml_eventdatalength[30];
            strEventdata = CString(pml_eventdata);
            _itoa(strEventdata.GetLength()/2, pml_eventdatalength, 10);
            strEventdata.TrimLeft();
            strEventdata.TrimRight();

            SQLAllocHandle(SQL_HANDLE_STMT, dbSession.hDbc, &hStmt01);
            lstrcpy( (char *) SqlStmt01, "BEGIN\n");
            lstrcat( (char *) SqlStmt01, "poc_pmlevent(3001");      //event type, voltage waveform
            lstrcat( (char *) SqlStmt01, ",0");                              //event channel, phase A
            lstrcat( (char *) SqlStmt01, ",'");
            lstrcat( (char *) SqlStmt01, pml_eventdate);                  //event date
            lstrcat( (char *) SqlStmt01, "',");
            lstrcat( (char *) SqlStmt01, pml_eventdatalength);      //event data length
            lstrcat( (char *) SqlStmt01, ",'");
            lstrcat( (char *) SqlStmt01, strEventdata);                  //raw binary data
            lstrcat( (char *) SqlStmt01, "',");
            lstrcat( (char *) SqlStmt01, instid);                              //instance key
            lstrcat( (char *) SqlStmt01, ",0);\n");                        //event flag, 0: not processed, 1: processed
            lstrcat( (char *) SqlStmt01, "END;\n");
            SQLExecDirect(hStmt01, SqlStmt01, lstrlen((char *)SqlStmt01));
            SQLFreeHandle(SQL_HANDLE_STMT, hStmt01);

            printf("Finish poc_pml %s \n", pml_eventdate);            

            inVr++;
            //Format string sent to pqhub - instid, timestamp, no of blob for Vr, Vy, Vb, Ir, Iy, Ib, In
            //sendbuf.Format("%s%d",instid, inVr); - tested ok
            sendbuf.Format("%s,%s,%d,%d,%d,%d,%d,%d,%d",instid, pml_eventdate, inVr, inVy, inVb, inIr, inIy, inIb, inIn);
            
            sendPQHub(sendbuf);
      
            retcode01 = SQLFetch( hstmt01 );

      }
      SQLFreeHandle(SQL_HANDLE_STMT, hstmt01);

      if(iChange==1)
      {
            SQLAllocHandle(SQL_HANDLE_STMT, dbSession.hDbc, &hStmt01);
            lstrcpy( (char *) SqlStmt01, "UPDATE instance SET v1ss_t=\'");
            lstrcat( (char *) SqlStmt01, pml_eventdate);
            lstrcat( (char *) SqlStmt01, "\' WHERE instid=");
            lstrcat( (char *) SqlStmt01, instid);
            lstrcat( (char *) SqlStmt01, ";");
            SQLExecDirect(hStmt01, SqlStmt01, lstrlen((char *)SqlStmt01));
            SQLFreeHandle(SQL_HANDLE_STMT, hStmt01);
      }
Exploring SQL Server 2016: Fundamentals

Learn the fundamentals of Microsoft SQL Server, a relational database management system that stores and retrieves data when requested by other software applications.

turbot_yuAuthor Commented:
the socket is in the sendPQHub(sendbuf);
jkrCommented:
Well, the startup/cleanup has to be done on a per process basis, threads are not affected (see http://msdn.microsoft.com/library/en-us/winsock/winsock/wsastartup_2.asp - "WSAStartup"). So, I'd suggest to completely remove that from your class and create a single global object that performs that for you, e.g.

class CWinsock
{
public:

    CWinsock  ()
    {
      // Initialize Winsock.
         WSADATA wsaData;
         int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
         if ( iResult != NO_ERROR )
              printf("Error at WSAStartup()\n");
    }

    ~CWinsock  ()
    {
        WSACleanup ();
    }
};
itsmeandnobodyelseCommented:
I moved your code to a class and made it thread-safe. The sample code compiles.

Regards, Alex


// simplesocket.h

#include <iostream>
#include <string>
using namespace std;

#include <winsock2.h>
#include <winbase.h>

class SimpleSocket
{
public:
    enum SocketStatus
    {
        INVALID,
        CREATED,
        CONNECTED,
        DISCONNECTED
    };

private:
    SOCKET       m_socket;
    SocketStatus m_status;

    static
    long   m_socketCount;   // count number of instances

public:
    SimpleSocket()
        : m_socket(INVALID_SOCKET),
          m_status(INVALID)

    {
        if (InterlockedIncrement(&m_socketCount) == 1)
        {
            // Initialize Winsock.
            WSADATA wsaData;
            int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
            if ( iResult != NO_ERROR )
            {
               cout << "Error at WSAStartup()" << endl;
               return;
            }
        }
        m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );

        if ( m_socket == INVALID_SOCKET )
        {
           cout << "Error at socket(): " << WSAGetLastError() << endl;
           return;
        }
        m_status = CREATED;

    }
    virtual ~SimpleSocket()
    {
        if (m_socketCount > 0 && InterlockedDecrement(&m_socketCount) == 0)
        {
            WSACleanup();
        }
    }

    bool isValid()
    {
        return !(m_socket == INVALID_SOCKET || m_status == INVALID);
    }

    bool isConnected()
    {
        return (m_status == CONNECTED);
    }

    bool connect(  const string& strIp, unsigned short usPort )
    {
        if (m_status == CREATED || m_status == DISCONNECTED )
        {
            // Connect to a server.
            sockaddr_in clientService;

            clientService.sin_family = AF_INET;
            clientService.sin_addr.s_addr = inet_addr( strIp.c_str() /* IP_ADDRESS_PQHUB */ );
            clientService.sin_port = htons( usPort/*PORT_PQHUB*/ );

            if ( ::connect( m_socket, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR)
            {
                cout << "Failed to connect. Error = " << WSAGetLastError() << endl;
                m_status = INVALID;
                return false;
            }
        }
        else
        {
            cout << "Failed to connect. Invalid socket status " << m_status << endl;
            return false;
        }
        m_status = CONNECTED;
        return true;
    }

    bool send( const string& sendbuf )
    {
        if (!isConnected())
            return false;

        int bytesSent = ::send( m_socket, sendbuf.c_str(), sendbuf.length()+1, 0 );
        if (bytesSent == SOCKET_ERROR)
        {
            cout << "Failed to send. Error = " << WSAGetLastError()  << endl;
            return false;
        }
        cout <<  "Bytes Sent: " << bytesSent << "  buf: " << sendbuf << endl;
        return true;
    }

};

// simplesocket.cpp

//include simplesocket.h  // uncomment if stored in two files

long SimpleSocket::m_socketCount = 0;  // init static counter

int main()
{
   SimpleSocket ssock;
   if (ssock.connect("192.168.0.1", 32123))
   {
       ssock.send("Hello World");
       return 0;
   }
   return 1;
}
turbot_yuAuthor Commented:
Hi Alex,

I am quite new in  c++.
May I know where should I put

   SimpleSocket ssock;

the given define in the int main().

Which one should I put it in?

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) or   //UploadData is in it

void UploadData(UploadParams strP[1]) or

void ulWF(LPVOID pParam) or


void UploadData(UploadParams strP[1])
{
      _beginthread(ulES, 0, strP);
      Sleep(1000);
      _beginthread(ulWF, 0, strP);
      Sleep(1000);
      _beginthread(ulSetup, 0, strP);
}


Thanks,

Turbot
turbot_yuAuthor Commented:
Should I put in within the loop or just outside the loop? Thanks Turbot
turbot_yuAuthor Commented:
In every loop, the UploadData( 3 thread will run once)
turbot_yuAuthor Commented:
When I put 'SimpleSocket ssock;' in int _tmain() and put

   if (ssock.connect("192.168.0.1", 32123))
   {
       ssock.send("Hello World");
       return 0;
   }
   return 1;

in ulWF()

It is said the ssock cannot be recognized when compile it.

May I know how to use it?

Thanks,

Turbot
itsmeandnobodyelseCommented:
>>>> May I know how to use it?

If you have a separate file for tmain function, say main.cpp, you need to

- store class SimpleSocket in simplesocket.h
- include simplesocket.h in your cpp file prior to using class SimpleSocket
- put the definition of the static member SimpleSocket::m_socketCount

     long SimpleSocket::m_socketCount = 0;  // init static counter

  to the cpp file below include of simplesocket.h.

Note, you may use the class in any cpp even in separate threads. Simply, include the header and use  it.

I tested the program above with VC++ 6.0. If you still have compile errors, please post the error and the line where it occurred.

Regards, Alex


turbot_yuAuthor Commented:
Hi Alex,

Thanks, now the error is generated is
D:\backup\desktop\power grid\pqhub\DTP\code\socket class by its\eventDTP\eventDTP.cpp(861) : error C2065: 'ssock' : undeclared identifier
D:\backup\desktop\power grid\pqhub\DTP\code\socket class by its\eventDTP\eventDTP.cpp(861) : error C2228: left of '.connect' must have class/struct/union type
D:\backup\desktop\power grid\pqhub\DTP\code\socket class by its\eventDTP\eventDTP.cpp(863) : error C2228: left of '.send' must have class/struct/union type
Error executing cl.exe.

eventDTP.exe - 3 error(s), 0 warning(s)

Now the case is:

1)  one file as simplesocket.h
2) eventDTP.cpp for main file
3) in eventDTP.cpp included
    #include "simplesocket.h"
    long SimpleSocket::m_socketCount = 0;  // init static counter
............
    int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
    {
............
          while ( iLoop < NO_OF_LOOPS )
          {
.............
                SimpleSocket ssock;
.............
      UploadData(strP);
.............
           }            
.............
     }
.............
void UploadData(UploadParams strP[1])
{
      _beginthread(ulES, 0, strP);
      Sleep(1000);
      _beginthread(ulWF, 0, strP);
      Sleep(1000);
      _beginthread(ulSetup, 0, strP);
}
.........
void ulWF(LPVOID pParam)
{
........
            if (ssock.connect("172.16.2.63", 11000))       //LINE 861
            {
                  ssock.send("Hello World");           //LINE 863
                  //return 0;
            }
..........
}

May I know how to solve it?

I just do not want to put the initial in the loop


turbot_yuAuthor Commented:
Sorry the main function should like this, the define is outside the loop

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{       SimpleSocket ssock;
............
         while ( iLoop < NO_OF_LOOPS )
          {
.............
         UploadData(strP);
.............
           }            
.............
     }
itsmeandnobodyelseCommented:
If you need ssock in ulWF you need to define it there:

#include "simplesocket.h"

void ulWF(LPVOID pParam)
{
      ...
      SimpleSocket ssock;
      if (ssock.connect("172.16.2.63", 11000))      
      {
           ssock.send("Hello World");      
          //return 0;
      }

}

If you need the connection in mre than one thread you may define it globally or define it in main and pass a pointer of that object to ulWF
You would need to add it to the the strP argument, e. g. by

struct Param
{
     char* strP;   // don't know the type of strP
     SimpleSocket* pSock;
};

void UploadData(Param* param);

int tmain(...)
{
    SimpleSocket ssock;

   while ( iLoop < NO_OF_LOOPS )
   {
          ...
          Param* p = new Param;
          p->strP = strP;
          p->psock = &ssock;
          UploadData(p);
          ...
    }              

    return 1;
}

In ulWF you need

void ulWF(void* param)
{
    Param* pParam = (Param*) param;
    SimpleSocket& ssock = *pParam->pSock;
    char* strP = pParam->strP;
    ...
}

Regards, Alex
turbot_yuAuthor Commented:
Thanks a lot,
Now the "hello" works well, I define the ssock in main.
One more small question.

The string need to send in socket is defined as,

CString sendbuf;
sendbuf.Format("%s,%s,%d,%d,%d,%d,%d,%d,%d",instid, pml_eventdate, inVr, inVy, inVb, inIr, inIy, inIb, inIn);

But it seem conflict with the type defined in socket class.  

bool send( const string& sendbuf )

The error code is,

D:\ym\DTP\code\socket class by its\eventDTP\eventDTP.cpp(859) : error C2664: 'send' : cannot convert parameter 1 from 'class CString' to 'const class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &'
        Reason: cannot convert from 'class CString' to 'const class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >'
        No constructor could take the source type, or constructor overload resolution was ambiguous

May you give any suggestion?

Thanks,

Turbot
itsmeandnobodyelseCommented:
>>>> May you give any suggestion?

I used class std::string cause I didn't know whether you are using MFC or not.

You may either call

   CString sendbuf;
   ...
   sssock.send(sendbuf.GetText()); // GetText gives a const char* what the compiler  
                                                   // converts to const std::string&


or use CString instead of string in class SimpleSocket (you would need to include stdafx.h in all cpp files prior to include simplesocket.h and don't need  to include <string>  and <winbase.h> headers).  Additionally, you have to remove .c_str() function calls or replace it by GetText() what is the equivalent function of class CString.

Regards, Alex

jkrCommented:
You haven't had a chance to try separating the Winsock startup code from your current solution or have yu decided to go that different way?
turbot_yuAuthor Commented:
The program may hang around 15th loop, may you seggest how to debug for it.
Thanks,

Turbot
turbot_yuAuthor Commented:
The program may hang around 15th loop after add the sock in, may you seggest how to debug for it.
Thanks,

Turbot
itsmeandnobodyelseCommented:
Please post the code part that hangs.

Regards, Alex
turbot_yuAuthor Commented:
The thing is difficullt to find where it hangs.
How to locate it?
:(
itsmeandnobodyelseCommented:
>>>> How to locate it?

Set a breakpoint to any loop.
itsmeandnobodyelseCommented:
Which Compiler/IDE you are using?

>>>>           while ( iLoop < NO_OF_LOOPS )

Do you increment iLoop counter somewhere? I couldn't find in the code posted.

Normally the loop in main() is infinite. After any loop cycle you need to check if either the user wants to stop the program or if all threads have finished. In both cases you would break the loop and exit.

int main()
{
      bool bUserExit     = false;
      bool startThreads = true;
      while (true)
      {
             // check abort by user (assume there is a thread where the user may abort the program)
             if (bUserExit)
             {
                    sendExitMessageToAllThreads();  // try to stop all threads smoothfully by setting a global exit flag
                    Sleep(2000);   // sleep a little while to give threads a chance to exit
                    break;     // break loop and exit
             }
             if (startThreads)
             {
                    UploadData(strP);
                    startThreads = false;
             }

             // check if all threads have exited
             if (!checkThreads())
                    break;   // break loop and exit cause no thread is active
             
             Sleep(100);       // sleep
      }
}

Note, the threads should be started only once. Then, they should have an infinite loop as well checking the exit flag set by the main thread and sleeping a little while at end of loop in order not pushing CPU to 100 percent.

In the main loop above there was no Sleep and UploadData always created new threads. That could be the reason for hanging as the number of threads for a process are limited.

Regards, Alex
turbot_yuAuthor Commented:
Hi Alex

Thanks a lot.

In testing, sometime the message will not be received by the other side.
But now, this message is quite important, since it is the one linking and triggerring to following part in the system.
Will there be any way to garantee the receipt and may you give some sample code.

Regards,

Turbot

It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Editors IDEs

From novice to tech pro — start learning today.