c++ - modbus tcp clent server with multiple slave id -


i'm working on win ce 6 modbus tcp client server, application developed client server communication , working fine. req slave device should respond diff slave addresses polled master/client. can change slave id , establish connection or need close previous connection , again establish new one

below code, working fine 1 node, if polled other node id gives exception. change req communicate other node simultaneously. device should able communicate 32 diff nodes on modbus tcp. shall create individual threads each node how communicate on same port? before establishing connection other node shall close previous node?

startupserver(int slaveaddr,  const tchar * const hostname) {     int result;    int tcpoption;    struct sockaddr_in hostaddress;     if (isstarted())       return (ftalk_illegal_state_error);     // note: tcp allow 0 slave address, -1 means ignore slave adr    if ((slaveaddr < -1) || (slaveaddr > 255))       return (ftalk_illegal_argument_error);    this->slaveaddr = slaveaddr;     //    // special treatment win32 platform, needs load winsock dll    // #ifdef _winsockapi_    wsadata wsadata;     result = wsastartup(0x0101, &wsadata);    if (result != 0)       return (ftalk_socket_lib_error); #endif     //    // open socket    //    listensocket = socket(pf_inet, sock_stream, 0);    if (listensocket == invalid_socket)    {       shutdownserver();       return (ftalk_open_err);    }     //    // configure listen socket options (we ignore errors here)    // #ifdef so_reuseaddr    tcpoption = 1; // enable option    setsockopt(listensocket, sol_socket, so_reuseaddr,               (char *) &tcpoption, sizeof (tcpoption)); #endif     //    // binding listen socket port    //    hostaddress.sin_family = af_inet;    if ((hostname == null) || (hostname[0] == '\0'))       hostaddress.sin_addr.s_addr = htonl(inaddr_any);    else    {       hostaddress.sin_addr.s_addr = inet_addr((char *) hostname); #if !defined(__vxworks__) // don't support host name resolving vxworks       if (hostaddress.sin_addr.s_addr == inaddr_none)       {          struct hostent *hostinfo;           hostinfo = gethostbyname((char *) hostname);           if (hostinfo == null)             return (ftalk_tcpip_connect_err);          hostaddress.sin_addr = *(struct in_addr *) hostinfo->h_addr;       } #endif    }    hostaddress.sin_port = htons(portno);    result = bind(listensocket, (struct sockaddr *) &hostaddress,                  sizeof (hostaddress));    if (result == socket_error)    {       shutdownserver();       switch (socketerrno)       { #ifdef _winsockapi_          case wsaeacces:          return (ftalk_port_no_access);          case wsaeaddrinuse:          return (ftalk_port_already_bound);          case wsaeaddrnotavail:          default:          return (ftalk_port_not_avail); #else          case enotconn: // linux 7.2 reports error no if no root privilege          case eacces:          return (ftalk_port_no_access);          case eaddrinuse:          return (ftalk_port_already_bound);          case eaddrnotavail:          default:          return (ftalk_port_not_avail); #endif       }    }     //    // start listening incoming connections    //    result = listen(listensocket,                ((max_connections < somaxconn) ? max_connections : somaxconn));    if (result == socket_error)    {       shutdownserver();       return (ftalk_listen_failed);    }    return (ftalk_success); }  serverloop() {    int ireturncode = (ftalk_success);    int result;    int sockidx;    int recvresult;    int sendresult;    fd_set fdset;    timeval timeval;    socket maxfiledes;    int replycnt;    int tcpoption;     if (!isstarted())       return (ftalk_illegal_state_error);     //    // prepare file descriptor set select call    //    fd_zero (&fdset); #ifdef _msc_ver #  pragma warning(push) #  pragma warning(disable: 4127) #endif    fd_set (listensocket, &fdset); #ifdef _msc_ver #  pragma warning(pop) #endif    maxfiledes = listensocket;    (sockidx = 0; sockidx < max_connections; sockidx++)    {       if (connectionsocketarr[sockidx] != invalid_socket) #ifdef _msc_ver #  pragma warning(push) #  pragma warning(disable: 4127) #endif          fd_set (connectionsocketarr[sockidx], &fdset); #ifdef _msc_ver #  pragma warning(pop) #endif       if (connectionsocketarr[sockidx] > maxfiledes)          maxfiledes = connectionsocketarr[sockidx];    }     //    // block until accept request or received data or time-out    //    timeval.tv_sec = (long) timeout / 1000l;    timeval.tv_usec = ((long) timeout % 1000l) * 1000l;    if (timeout == 0)       result = select((int) maxfiledes + 1, &fdset, null, null, null);    else       result = select((int) maxfiledes + 1, &fdset, null, null, &timeval);    if (result == socket_error)       return (ftalk_filedes_exceeded);     //    // check time-out    //    if (result == 0)    {       tracelog1("slave poll time-out!\n");       datatableptr->timeouthandler();        ireturncode = (ftalk_reply_timeout_error);    }     //    // connection accept request    //    if (fd_isset (listensocket, &fdset))    {       // search free socket       (sockidx = 0; sockidx < max_connections; sockidx++)       {          if (connectionsocketarr[sockidx] == invalid_socket)          {             struct sockaddr_in peeraddr;             sock_len_type peeraddrlen = sizeof(peeraddr);              // yes, socket free, try accept connection on             connectionsocketarr[sockidx] = accept(listensocket,                                                   (struct sockaddr *) &peeraddr,                                                   &peeraddrlen);             if (connectionsocketarr[sockidx] != invalid_socket)             {                //                // check id connection shall accepted                //                if (!datatableptr->validatemasteripaddr(inet_ntoa(peeraddr.sin_addr)))                {                   shutdown(connectionsocketarr[sockidx], sd_both);                   closesocket(connectionsocketarr[sockidx]);                   connectionsocketarr[sockidx] = invalid_socket;                   tracelog2("connection rejected on slot %d\n", sockidx);                }                 //                // set socket options (we ignore errors here, not critical)                // #ifdef tcp_nodelay                tcpoption = 1; // enable option                setsockopt(connectionsocketarr[sockidx],                           ipproto_tcp, tcp_nodelay,                           (char *) &tcpoption, sizeof (tcpoption)); #endif #ifdef so_sndbuf                tcpoption = max_msg_size;                setsockopt(connectionsocketarr[sockidx],                           sol_socket, so_sndbuf,                           (char *) &tcpoption, sizeof (tcpoption)); #endif #ifdef so_rcvbuf                tcpoption = max_msg_size;                setsockopt(connectionsocketarr[sockidx],                           sol_socket, so_rcvbuf,                           (char *) &tcpoption, sizeof (tcpoption)); #endif #ifdef so_linger                tcpoption = 0; // disable option = discard unsent data when closing                setsockopt(connectionsocketarr[sockidx],                           sol_socket, so_linger,                           (char *) &tcpoption, sizeof (tcpoption)); #endif                tracelog2("connection accepted on slot %d\n", sockidx);             }             break; // leave loop          }       }    }     //    // data received on socket    //     (sockidx = 0; sockidx < max_connections; sockidx++)    {       if (connectionsocketarr[sockidx] != invalid_socket)       {          if (fd_isset (connectionsocketarr[sockidx], &fdset))          {             recvresult = recv (connectionsocketarr[sockidx],                                (char *) bufferarr, sizeof (bufferarr), 0);             sendresult = 0;             replycnt = 0;              //             // process client message             //             if (recvresult >= prefix_len) // process minimum message sizes             {                short datalen;                 datalen = (short) ((bufferarr[4] << 8) | (bufferarr[5] & 0xff));                // validate length before processing message                if ((datalen + prefix_len) == recvresult)                {                   replycnt = processmessage(&bufferarr[prefix_len],                                             recvresult - prefix_len);                    // first 2 bytes (msg id) returned untouched                   bufferarr[2] = 0; // protocol identifier                   bufferarr[3] = 0; // protocol identifier                   bufferarr[4] = (char) ((replycnt) >> 8);                   bufferarr[5] = (char) ((replycnt) & 0xff);                   sendresult = send(connectionsocketarr[sockidx],                                     (char *) bufferarr,                                     replycnt + prefix_len, 0);                }             }             //             // check disconnection , errors             //             if ((recvresult < prefix_len) ||                 (sendresult != replycnt + prefix_len))             {                //                // free socket                //                shutdown(connectionsocketarr[sockidx], sd_both);                closesocket(connectionsocketarr[sockidx]);                connectionsocketarr[sockidx] = invalid_socket;                if (recvresult == 0)                   tracelog2("disconnected slot %d nicely other peer.\n",                             sockidx);                else                   tracelog2("forced disconnection on slot %d!\n", sockidx);             }          }       }    }    return ireturncode; } 

will below code resolve problem?

int modbustcpslave::serverloop() {    int ireturncode = (ftalk_success);    int result;    int sockidx;    int recvresult;    int sendresult;    fd_set fdset;    timeval timeval;    socket maxfiledes;    int replycnt;    int tcpoption;     //if (!isstarted())    //   return (ftalk_illegal_state_error);     //    // prepare file descriptor set select call    // //   fd_zero (&fdset); //#ifdef _msc_ver //#  pragma warning(push) //#  pragma warning(disable: 4127) //#endif //   fd_set (listensocket, &fdset); //#ifdef _msc_ver //#  pragma warning(pop) //#endif //   maxfiledes = listensocket; //   (sockidx = 0; sockidx < max_connections; sockidx++) //  { //      if (connectionsocketarr[sockidx] != invalid_socket) //#ifdef _msc_ver //#  pragma warning(push) //#  pragma warning(disable: 4127) //#endif //         fd_set (connectionsocketarr[sockidx], &fdset); //#ifdef _msc_ver //#  pragma warning(pop) //#endif //      if (connectionsocketarr[sockidx] > maxfiledes) //         maxfiledes = connectionsocketarr[sockidx]; //   }     //    // block until accept request or received data or time-out    //    timeval.tv_sec = (long) timeout / 1000l;    timeval.tv_usec = ((long) timeout % 1000l) * 1000l;    if (timeout == 0)       result = select((int) maxfiledes + 1, &fdset, null, null, null);    else       result = select((int) maxfiledes + 1, &fdset, null, null, &timeval); //   if (result == socket_error) //      return (ftalk_filedes_exceeded);     //    // check time-out    // //   if (result == 0) //   { //      tracelog1("slave poll time-out!\n"); //      datatableptr->timeouthandler(); // //    ireturncode = (ftalk_reply_timeout_error); //   }     //    // connection accept request    //  //  if (fd_isset (listensocket, &fdset))    {       // search free socket  //     (sockidx = 0; sockidx < max_connections; sockidx++)       {   //       if (connectionsocketarr[sockidx] == invalid_socket)          {             struct sockaddr_in peeraddr;             sock_len_type peeraddrlen = sizeof(peeraddr);              // yes, socket free, try accept connection on             connectionsocketarr[sockidx] = accept(listensocket,                                                   (struct sockaddr *) &peeraddr,                                                   &peeraddrlen); //           if (connectionsocketarr[sockidx] != invalid_socket) //           { //               // //               // check id connection shall accepted //               // //               if (!datatableptr->validatemasteripaddr(inet_ntoa(peeraddr.sin_addr))) //               { //                  shutdown(connectionsocketarr[sockidx], sd_both); //                  closesocket(connectionsocketarr[sockidx]); //                  connectionsocketarr[sockidx] = invalid_socket; //                  tracelog2("connection rejected on slot %d\n", sockidx); //               }                 //                // set socket options (we ignore errors here, not critical)                // //#ifdef tcp_nodelay //               tcpoption = 1; // enable option //               setsockopt(connectionsocketarr[sockidx], //                          ipproto_tcp, tcp_nodelay, //                          (char *) &tcpoption, sizeof (tcpoption)); //#endif //#ifdef so_sndbuf //               tcpoption = max_msg_size; //               setsockopt(connectionsocketarr[sockidx], //                          sol_socket, so_sndbuf, //                          (char *) &tcpoption, sizeof (tcpoption)); //#endif //#ifdef so_rcvbuf //               tcpoption = max_msg_size; //               setsockopt(connectionsocketarr[sockidx], //                          sol_socket, so_rcvbuf, //                          (char *) &tcpoption, sizeof (tcpoption)); //#endif //#ifdef so_linger //               tcpoption = 0; // disable option = discard unsent data when closing //               setsockopt(connectionsocketarr[sockidx], //                          sol_socket, so_linger, //                          (char *) &tcpoption, sizeof (tcpoption)); //#endif //               tracelog2("connection accepted on slot %d\n", sockidx); //            } //           break; // leave loop //         } //      } //   }     //    // data received on socket    //  //   (sockidx = 0; sockidx < max_connections; sockidx++) //   { //      if (connectionsocketarr[sockidx] != invalid_socket) //    { //         if (fd_isset (connectionsocketarr[sockidx], &fdset)) //         {             recvresult = recv (connectionsocketarr[sockidx],                                (char *) bufferarr, sizeof (bufferarr), 0);             sendresult = 0;             replycnt = 0;              //             // process client message             //             if (recvresult >= prefix_len) // process minimum message sizes             {                short datalen;                 datalen = (short) ((bufferarr[4] << 8) | (bufferarr[5] & 0xff));                // validate length before processing message                if ((datalen + prefix_len) == recvresult)                {                   replycnt = processmessage(&bufferarr[prefix_len],                                             recvresult - prefix_len);                    // first 2 bytes (msg id) returned untouched                   bufferarr[2] = 0; // protocol identifier                   bufferarr[3] = 0; // protocol identifier                   bufferarr[4] = (char) ((replycnt) >> 8);                   bufferarr[5] = (char) ((replycnt) & 0xff);                   sendresult = send(connectionsocketarr[sockidx],                                     (char *) bufferarr,                                     replycnt + prefix_len, 0);                }             }             //             // check disconnection , errors             //             if ((recvresult < prefix_len) ||                 (sendresult != replycnt + prefix_len))             {                //                // free socket                //                shutdown(connectionsocketarr[sockidx], sd_both);                closesocket(connectionsocketarr[sockidx]);                connectionsocketarr[sockidx] = invalid_socket;                if (recvresult == 0)                   tracelog2("disconnected slot %d nicely other peer.\n",                             sockidx);                else                   tracelog2("forced disconnection on slot %d!\n", sockidx);             } //         } //    } //   }    return ireturncode; } 

thanks valter, right, got it. i've 1 more query in code there 2 arrays regdata[30][65535]; , bitarray[30][2000] after reading data file can decide first dimension of array i.e. [30]..if data in file 2 slave id require regdata[2][65535] , bitarray[2][2000]..how can manage assignment @ runtime? tried using vector struct{ regdata[65535]; bitarray[2000]; }regstack; after reading file i tried push_back() regstack, gives heap error..how can resize array in runtime?

you can't have multiple sockets listening on same port. if address validated inside processmessage couln't change function accept requests different slave ids.


Comments

Popular posts from this blog

python - Subclassed QStyledItemDelegate ignores Stylesheet -

java - HttpClient 3.1 Connection pooling vs HttpClient 4.3.2 -

SQL: Divide the sum of values in one table with the count of rows in another -