Skip to content
Snippets Groups Projects
Select Git revision
  • 166e1897febe71a710a56c2e5c3ca56f5087f565
  • main default protected
  • cobalt2.1 protected
  • cobalt2.1-ci-cd-spackv2a
  • update
  • cobalt2.1-ci-cd-spack
  • fix-btl-tcp-args
  • cobalt3 protected
8 results

configure.sh

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    tcpsocket.cpp 5.18 KiB
    /*
     * Copyright 2020 Stichting Nederlandse Wetenschappelijk Onderzoek Instituten,
     * ASTRON Netherlands Institute for Radio Astronomy
     * Licensed under the Apache License, Version 2.0 (the "License");
     *
     * you may not use this file except in compliance with the License.
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     *
     * See ../../LICENSE.txt for more info.
     */
    
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/ioctl.h> 
    #include <arpa/inet.h> // htons
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <netdb.h>
    #include <fcntl.h>
    //#include <syslog.h>
    #include <errno.h>
    #include <iostream>
    #include <sstream>
    #include <string.h>
    #include <stdexcept>
    
    #include "tcpsocket.h"
    
    
    /*
       TCP Server Socket listens to port p and binds to interface iface.
       Set iface="" to not bind to an interface.
    */
    TCPSSocket::TCPSSocket(uint16_t p, const char* iface, int maxservers)
    {
        port = p;
        MaxServers = maxservers;
        sock = socket(PF_INET, SOCK_STREAM, 0);
        if (sock < 0) 
            throw runtime_error("TCPSSocket: socket creation error"); 
        int val = 1;
        if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) {
            close(sock);
            cerr << "Error: " << strerror(errno) << endl;
            throw runtime_error("TCPSSocket: cannot set socket option SO_REUSEADDR");
        }
    
        /* Give the socket a name. */
        name.sin_family = AF_INET;
        name.sin_port = htons (port);
        name.sin_addr.s_addr = htonl (INADDR_ANY);
    
        if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) {
            close(sock);
            cerr << "Error: " << strerror(errno) << endl;
            throw runtime_error("TCPSSocket: cannot bind socket");
        }
    }
    
    TCPSSocket::~TCPSSocket()
    {
      close(sock);
    }
    
    int TCPSSocket::listen(void)
    {
        ostringstream strs;
        printf("Listening to tcp port %d\n",port);
    
    //    syslog(LOG_INFO,"Listening to tcp port %d\n",port);
        if (::listen (sock, 1) < 0) 
            throw runtime_error("TCPSSocket::listen: cannot put socket into listening state");
    
        /* Block until input arrives on the server socket. */
        int nsock;
        struct sockaddr_in clientname;
        socklen_t size = sizeof (clientname);
    
        nsock = accept (sock,(struct sockaddr *) &clientname,&size);
        if (nsock < 0) {
            cerr << "Error TCPSSocket::listen() accept(): " << strerror(errno) << endl;
            exit(-1);
        }
    
        struct hostent *he;
        he = gethostbyaddr(&clientname.sin_addr, sizeof clientname.sin_addr, AF_INET);
    
        strs << "Server: Client connect from host "
             << (he ? he->h_name : inet_ntoa (clientname.sin_addr)) << " (" << inet_ntoa (clientname.sin_addr)
             << "):" <<  ntohs(clientname.sin_port) << endl;
    
    //    syslog(LOG_INFO,"%s",strs.str().c_str());
    
        return nsock;
    }
    
    TCPCSSocket::TCPCSSocket(int s)
    {
        sock = s;
    }
    
    TCPCSSocket::~TCPCSSocket()
    {
      close(sock);
    }
    
    size_t TCPCSSocket::rx(unsigned char *buf, size_t len)
    /*
       Receive max len bytes from a TCP socket
       This one stops after one packet and returns the 
       number of actual received bytes
    */
    {
        size_t nrx = 0;
        ssize_t ret;
        do {
            fd_set readfds;
            FD_ZERO(&readfds);
            FD_SET(sock, &readfds);
            // No time out
            if(select(sock + 1, &readfds, NULL, NULL, NULL) == -1) {
                throw runtime_error("TCPCSSocket::rx: select error");
            }
            if FD_ISSET(sock, &readfds) {
                ret = recvfrom(sock, buf, len, 0, NULL, NULL);
                if(ret == -1) {
                    throw runtime_error("TCPCSSocket::rx(): recvfrom=-1 error"); 
                } else if(ret == 0) {
                    throw runtime_error("TCPCSSocket::rx(): recvfrom=0 peer orderly shutdown");
                }
                nrx += ret;
                break;
            }
        } while (1);
        return nrx;
    }
    
    size_t TCPCSSocket::_rx(unsigned char *buf, size_t len)
    /*
       Receive len bytes from a TCP socket
    */
    {
        size_t nrx = 0;
        ssize_t ret;
        //struct timeval timeout;
        //timeout.tv_sec = timeoutms / 1000;
        //timeout.tv_usec = ( timeoutms % 1000 ) * 1000;
       
        // Receive a datagram from a tx source
        do {
            fd_set readfds;
            FD_ZERO(&readfds);
            FD_SET(sock, &readfds);
            // No time out
            if(select(sock + 1, &readfds, NULL, NULL, NULL) == -1) {
                throw runtime_error("TCPCSSocket::_rx: select error");
            }
            if FD_ISSET(sock, &readfds) {
                ret = recvfrom(sock, &buf[nrx], len-nrx, 0, NULL, NULL);
                if(ret == -1) { 
                    throw runtime_error("TCPCSSocket::_rx(): recvfrom=-1 error"); 
                } else if(ret == 0) {
                    throw runtime_error("TCPCSSocket::_rx(): recvfrom=0 peer orderly shutdown");
                }
                nrx += ret;
            }
            if (nrx==len)
                break;
        } while (1);
        return nrx;
    }
    
    size_t TCPCSSocket::tx(const unsigned char* mes, size_t len)
    {
        int ntxbytes = write(sock, mes, len);
        if (ntxbytes < 0) 
            throw runtime_error("TCPCSSocket::tx(): could not send message");
        return ntxbytes;
    }