1

Currently, my python server is not accepting clients correctly... I'm really baffled because it works with a python TCP client. When I run a C++ application that is trying to connect to the python server the Python server blocks at accepting and doesn't accept the C++ client.

I've written a C# TCP Server and this seems to accept C++ client.

Is there something I'm missing that's special between python and c++? My intuition tells me it might have to do with the way the sockets are configured? Could endianness play a role here?

My Python client code is here:

    def fn_connect(self,
               ip,
               port):
        logging.debug("Connecting using {0}:{1} Address".format(ip, port))
        self.__ip = ip
        self.__port = int(port)
        self.__tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        try:
            self.__tcp_socket.bind((self.__ip, self.__port))
        except:
            logging.info(traceback.format_exc())
            logging.info("Failed to bind socket")
            return

        _backlog = 255
        self.__tcp_socket.listen(_backlog)

        # Start threading
        self.waiting_thread = threading.Thread(target = \
            self._fn_wait_for_connections)

        self.waiting_thread.daemon = True
        self.waiting_thread.start()

    def _fn_wait_for_connections(self):
        self.__running_waiting = True

        while(self.__running_waiting):
            try:
                print "GOT HERE?"
                _client_socket, _address = self.__tcp_socket.accept()
                print "DONE?"
            except:
                logging.error(traceback.format_exc())
                break
            _client_ip = _address[0]
            _client_port = _address[1]

The C++ code is:

    char sendbuf[1024];
    char recvbuf[1024];
    int str_len;
    struct sockaddr_in serv_addr;

    signal(SIGUSR1,handler);
    sockfd = socket(AF_INET, SOCK_STREAM, 0);   
    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = inet_addr(server_ip);
    serv_addr.sin_port = htons(atoi(server_port));

    int error=-1,len;
    len=sizeof(int);
    timeval tm;
    fd_set set;
    unsigned long ul = 1;
    ioctl(sockfd, FIONBIO, &ul);
    bool ret=false;
retry:
    if(connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1)
    {

        tm.tv_sec=TIME_OUT_TIME;
        tm.tv_usec=0;
        FD_ZERO(&set);
        FD_SET(sockfd,&set);
        if(select(sockfd+1,NULL,&set,NULL,&tm)>0)
        {
            getsockopt(sockfd,SOL_SOCKET,SO_ERROR,&error,(socklen_t *)&len);
            if(error==0) 
                ret=true;
            else 
            {
                ret=false;
                sleep(1);
                goto retry;
            }
        }else {
            ret=false;
            sleep(1);
            goto retry;
        }
    }
    else 
    {
        printf("Connect\n");
        ret=true;
    }
tyleax
  • 1,556
  • 2
  • 17
  • 45
  • The code of your C++ is incomplete - especially the retry label is missing. And, please try with a blocking connect first because it is much simpler and the chance of making errors is thus smaller - and you are making such errors at least by not checking the error code returned from the failed connect and just treat all errors as a temporary error. And, add the output of the several debug statements in your code to the question too. Also, add such debug statements for any errors you get, like the errno you get from a failing connect statement. – Steffen Ullrich Aug 03 '17 at 04:39
  • @SteffenUllrich Thanks for pointing that out. The C++ code isn't mine but I do have the source. I was trying to strip anything that I thought was unnecessary so you didn't need to parse through as much code. let me know if this looks better now. Also it doesn't explain why it works with a C# Server but not on a Python server. – tyleax Aug 03 '17 at 06:26
  • To cite myself: *"... try with a blocking connect first ... not checking the error code...and just treat all errors as a temporary error...add the output of the several debug statements in your code to the question too..."*. None of this is addressed. Also, the retry label is placed at the wrong place, i.e. [non-blocking connect](https://stackoverflow.com/questions/17769964/) is done wrong. I have the feeling that you don't actually understand the C code you are posting. – Steffen Ullrich Aug 03 '17 at 07:05
  • As for why it works with C# vs. Python: it might be due to the non-blocking connect succeeding against the C# server on the first try while not doing this against the Python server. Such quick connect often happens if you connect to a server on the same system but is also depending on the underlying operating system. In any case - your non-blocking connect is simply wrong and will only work if the first connect succeeds already. – Steffen Ullrich Aug 03 '17 at 07:07

0 Answers0