0

While running this server code for 2nd time, I get this error

"Binding failed: Cannot assign requested address".

I am using RE_USEADDR, but still facing the problem. I understand the server is not getting closed after use.

command line input:

arg[1]=127.0.0.1, arg[2]=5019

Code

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>

void reverse(char*, int, int);

int main(int argc, char* argv[]){
int welcomeSocket, newSocket;
char buffer[1024];
struct sockaddr_in serverAddr;
struct sockaddr_storage serverStorage;
socklen_t addr_size;
int val=1;

bzero((char*)&serverAddr,sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(atoi(argv[2]));
serverAddr.sin_addr.s_addr = htonl(argv[1]);
if((welcomeSocket = socket(AF_INET, SOCK_STREAM, 0))==-1){
        perror("socket err");
        exit(1);}


memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);

setsockopt(welcomeSocket, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(int));

if(bind(welcomeSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr))<0){
    perror("Binding failed\n");
    exit(1);}

if(listen(welcomeSocket,5)==0)
    printf("Listening\n");
else
    printf("Error\n");

while(1){
    printf("1");
    addr_size = sizeof(serverStorage);
    newSocket = accept(welcomeSocket, (struct sockaddr *) &serverStorage, &addr_size);

    recv(newSocket, buffer, 1024, 0);
    printf("Data received: %s",buffer);

    reverse(buffer, 0, strlen(buffer)-1);
    send(newSocket,buffer,13,0);

    close(newSocket);
}
close(welcomeSocket);
return 0;
}

I expect it to work every time irrespective to its ip and port.

EsmaeelE
  • 1,681
  • 5
  • 15
  • 22
  • You aren't checking the return from recv. There is no guarantee that a complete buffer is sent in a single packet. – stark Aug 20 '19 at 23:02
  • Also, you're doing strlen on a buffer that is not guaranteed to be null-terminated. – stark Aug 20 '19 at 23:04
  • *I am using `RE_USEADDR`, but still facing the problem"* - I believe it is `SO_REUSEADDR`. Also see [How do SO_REUSEADDR and SO_REUSEPORT differ?](https://stackoverflow.com/q/14388706/608639) and friends. You may be restarting too soon. In this case, reduce `SO_LINGER`. Lingering helps with client shutdowns in transit to the old [dead] server. – jww Aug 21 '19 at 02:49

2 Answers2

2

The htonl function expects a 32 bit integer value. You are instead passing the address of a string, so you are actually attempting to use this address, converted to a 32 bit value in network byte order, as an IP address.

You instead want to pass the string to inet_addr which converts the string representation of an IPv4 address to a 32 bit value in network byte order.

serverAddr.sin_addr.s_addr = inet_addr(argv[1]);
dbush
  • 162,826
  • 18
  • 167
  • 209
-1

When you come out of the program, the socket is not closed gracefully. I would recommend use the signal interrupt handler and close the welcomeSocket.

void sigintHandler(int sig_num) {
close(welcomeSocket);
}

int main(){
signal(SIGINT, sigintHandler);
...
...
your code
while (1) {
  //code
}

}