1

I have written a simple socket server in c++ in CentOS 7.0 using the famous Berkeley socket interface. I run it, on whatever port, and it waits for the connections.

I then run my simple client program also written with c++ and send a request to 192.168.122.1 (this IP is found through executing command ip addr) but it refuses to connect. Being concerned with the firewall, I stop the httpd.service (APACHE) and do the procedure on port 80, but to no avail and I receive the error "Connection Refused".

What should I do?

** UPDATE 001 ** when I run the command netstat -l I get the following output:

.
.
tcp        0      0 0.0.0.0:9005            0.0.0.0:*               LISTEN
.
.

** END OF UPDATE 001 ** Here are the outputs:

Client --> Connection Refused

Server --> [Waiting...]

Here are the codes:

CLIENT:

#include <iostream>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <cstring>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>



using namespace std;


namespace TCP {
    class Client {

    public :
        static bool Connect(int argc, char *argv[]) {


            int returnStatus = 0;


            char* buffer[256];


            if (3 != argc) {
                // warn that the port MUST be specified.
                fprintf(stderr, "Incorrect parameter for port and server's address. Usage: %d <port>.\n", argv[0]);
                exit(1); // shut down the application
            }


            // streaming socket is the same as server's one.
            // Note: we use TCP Streaming and not UDP's datagram.
            int socketObject = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);



            //
            struct sockaddr_in serverObject;

            short int portNumber = atoi(argv[1]);

            /**
             * We use memset() of cstring header
             * to set all uninitialized values of
             * the struct serverObject to zero.
             */
            memset(&serverObject,
                   0, sizeof(serverObject));

            // now set the values properly
            serverObject.
                    sin_family = AF_INET;


            serverObject.sin_addr.s_addr = inet_addr(argv[2]);

            serverObject.
                    sin_port = htons(portNumber);


            // we need now to connect to the server by porting out
            // out socketObject
            returnStatus = connect(socketObject, (sockaddr *)&serverObject, sizeof(serverObject));

            if (returnStatus == 0) {
                fprintf(stdout, "Connect successfully done.");
            }
            else {
                fprintf(stderr, "Connection failed! Error %s\n", strerror(errno));
                close(socketObject);

                exit(errno);
            }

            // now it's time to read the data from the server by using read()
            // we read it up to the point of our buffer size
            returnStatus = read(socketObject, buffer, sizeof(buffer));


            if (returnStatus == -1) {
                fprintf(stderr, "cannot read the data.");
                close(socketObject);
                exit(1);
            }
            else if( returnStatus > 0)
            {
                cout << buffer << endl;
                close(socketObject);
            }
        }
    };
}// end of namespaCE

SERVER

#include <iostream>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <cstring>
#include <unistd.h>



using namespace std;

const char DATA_BACK_TO_CLIENT[] = "A simple socket server!";

namespace TCP {
    class Server {

    public :
        static bool Connect(int argc, char *argv[]) {

            int returnStatus = 0;

            if (2 != argc) {
                // warn that the port MUST be specified.
                fprintf(stderr, "Incorrect parameter for port. Usage: %d <port>.\n", argv[0]);
                exit(1); // shut down the application
            }

            int socketObject = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

            struct sockaddr_in serverObject;

            int portNumber = atoi(argv[1]);

            /**
     * We use memset() of cstring header
     * to set all uninitialized values of
     * the struct serverObject to zero.
     */
            memset(&serverObject,
                   0, sizeof(serverObject));

            // now set the values properly
            serverObject.
                    sin_family = AF_INET;
            serverObject.sin_addr.
                    s_addr = htonl(INADDR_ANY);
            serverObject.
                    sin_port = htonl(portNumber);


            returnStatus = bind(socketObject, (struct sockaddr *) &serverObject,
                                sizeof(serverObject));

            if (returnStatus != 0) {
                fprintf(stderr, "Cannot do the binding. Socket closed.");
                close(socketObject);
                exit(1);
            }

            returnStatus = listen(socketObject, 5); // 5 is a typical value for backlog
            // which denotes the number of allowed connections in queue, After linux 2.2,
            // only completed connections are counted in the queue.

            if (returnStatus == -1) {
                fprintf(stderr, "Cannot listen on the socketl.");
                close(socketObject);
                exit(1);
            }

            while (1) {
                cout << "Server has started successfully. Info:" << endl;
                cout << "Port Number Listening to: " <<  portNumber << endl;

                int simpleChildSocket = 0;
                struct sockaddr clientSocket = {0};
                int simpleClient = 0;
                socklen_t clientNameLength = sizeof(clientSocket);


                cout << "Listening Status:" << returnStatus << endl;

                /** blocking-state. accept() is a blocking
                 *  function essentially.
                 * **/
                simpleChildSocket = accept(socketObject, &clientSocket,
                                           &clientNameLength);
                cout << "Accept Connection Status: " << simpleChildSocket << endl;
                if (simpleChildSocket == -1) {
                    fprintf(stderr, "Cannot accept connectios.\n");
                    close(socketObject);
                    exit(1);
                }

                /**
         * Handle the incoming request
         * write received data from the server
         */
                write(simpleChildSocket, DATA_BACK_TO_CLIENT, sizeof(DATA_BACK_TO_CLIENT));

                // closing the child socket
                close(simpleChildSocket);
            }

            close(socketObject);
        }
    };
}// end of namespaCE
Mostafa Talebi
  • 8,825
  • 16
  • 61
  • 105
  • 2
    The port number is set with `htons()`, not `htonl()`. – user207421 Feb 24 '16 at 11:01
  • 1
    Without looking at your code, when you're running the server, check that it is working as expected by running `netstat -l` to check that your pid is listening to the port you're expecting. Then on the local box run `telnet localhost ` to see if that connects, this rules out server code issues. If it does, do the telnet from the remote box and see if that connects. This rules out firewall issues. After that the only remaining thing to check is your client code. – Salgar Feb 24 '16 at 11:08
  • Salgar I check your suggestion, and report back – Mostafa Talebi Feb 24 '16 at 11:09
  • @Salgar I have updated the question with the result of netstat. When I execute it, for port 9005 which is my test port for the server, I get: `tcp 0 0 0.0.0.0:9005 0.0.0.0:* LISTEN` – Mostafa Talebi Feb 24 '16 at 11:26
  • It is working. Thank you @EJP The problem was `htols()` which had to be used for port integer convertion. You can post it as an answer. – Mostafa Talebi Feb 24 '16 at 11:28

1 Answers1

2

The port number needs to be set with htons(), not htonl().

user207421
  • 305,947
  • 44
  • 307
  • 483