1

I am fairly new to socket programming. I saw a tutorial and tried implementing the programs in my Linux machine. The codes are :

CLIENT :

int main() {

char buf[256] = "In client";


// create the socket
int sock;
sock = socket(AF_INET, SOCK_STREAM, 0);

//setup an address
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = INADDR_ANY;
server_address.sin_port = htons(9002);

int status  =  connect(sock, (struct sockaddr *) &server_address, sizeof(server_address));
if(status == -1)
{

        printf("There Was an error!");
}

recv(sock, buf, sizeof(buf), 0);

printf("\n %s \n", buf);
close(sock);

return 0;
}

SERVER:

int main() {

char server_message[256] = "You have reached the server!";

// create the server socket
int server_socket;
server_socket = socket(AF_INET, SOCK_STREAM, 0);


// define the server address
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(9002);
server_address.sin_addr.s_addr =  INADDR_ANY;

// bind the socket to our specified IP and port
bind(server_socket, (struct sockaddr*) &server_address, sizeof(server_address));

listen(server_socket, 5);

int client_socket;
client_socket = accept(server_socket, NULL, NULL);

// send the message
send(client_socket, server_message, sizeof(server_message), 0);

// close the socket
close(server_socket);

return 0;
}

The code is self-explanatory. When I run the server and then the client, for the first time, it works. But when I do it again, just after the previous one, the Client gives the message - There Was an error!, that means the connection is not happening.

Can anyone help why is this occurring? Thanks in advance!

Akash
  • 939
  • 1
  • 8
  • 27
  • There are many errors. Not handling completely and correctly the result of system calls, assuming NUL-terminated buffers when it's not guaranteed. The usual. – Martin James Aug 22 '17 at 18:56
  • Can you please elaborate on the errors @MartinJames. I want to learn how are they causing problems. – Akash Aug 22 '17 at 19:00
  • Try connecting to INADDR_LOOPBACK instead of INADDR_ANY? – user253751 Aug 23 '17 at 01:12

2 Answers2

1

You should be checking for errors for all system calls in your server. I'm guessing that your bind is failing, because the port is "already in use". The reason for this is that the connection from the previous instance of the server lingers for a while in the operating system's connection table.

You want to use setsockopt with SO_REUSEADDR to avoid the bind failure. Specifically, add this prior to the bind call.

int reuse = 1;
if (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0)
    perror("setsockopt(SO_REUSEADDR) failed");

(And do check errors. Makes debugging these kinds of things much easier if you know when something fails. Also, use perror or strerror(errno) in order to find out exactly why it failed -- not just that it failed.)

Gil Hamilton
  • 11,973
  • 28
  • 51
  • This worked. What deos the `setsockopt` do? Does this enforces the bind ? – Akash Aug 22 '17 at 18:59
  • 1
    It allows the re-use of a port that still has `TIME_WAIT` connections in the OS connection table. After running your server/client once, execute `netstat -atn | grep 9002` to see the entries. Ordinarily these entries prevent re-use of that port for a time (the exact duration is OS-dependent). See also https://stackoverflow.com/a/3233082/1076479 for more explanation – Gil Hamilton Aug 22 '17 at 20:01
1

Check out my whole code here and see how it runs.

This is the server

int main(){
    SOCKET s, newsocket;
    struct sockaddr_in server, client;
    int receiving;
    char clientMessage[2000], *message;

    if((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET){
        printf("socker error at %d", GetLastError());
    }else{
        puts("socket created");
    }

    server.sin_addr.s_addr = inet_addr("127.0.0.1");
    server.sin_family = AF_INET;
    server.sin_port = htons(8080);

    if(bind(s, (struct sockaddr*)&server, sizeof(server)) < 0){
        printf("err at binding %d", GetLastError());
    }else{
        puts("binded.");
    }

    listen(s, 3);

    puts("listening to connections...");

    int c = sizeof(struct sockaddr_in);

    while((newsocket = accept(s, (struct sockaddr*)&client, &c)) != INVALID_SOCKET){
        puts("connection accepted");
        //send 
        message="hello client";
        send(newsocket, message, strlen(message), 0);
        recv(newsocket, clientMessage, 50, 0);
        puts(clientMessage);

    }

    puts("waiting for a machine");

    if(newsocket == INVALID_SOCKET){
        printf("newsocket invalid at %d", GetLastError());
    }




    getchar();
    closesocket(s);
    WSACleanup();
}

This is the client

int main(){
    SOCKET s;
    struct sockaddr_in server;

    if((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET){
        printf("socket error At %d", GetLastError());
    }else{
        puts("socket initialised");
    }

    server.sin_port = htons(8080);
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = inet_addr("176.40.201.72");

    printf("server values are defined.. \n");
    printf("connecting..\n");

    if(connect(s, (struct sockaddr*)&server, sizeof(server)) < 0){
        printf("connection error %d" , GetLastError());
    }else{
        puts("connected");
    }

    return 0;
}