0

I'm creating a server/clinet, but I've a problem. If I boot the server and the client for the first time, everthing works fine. Then I close them, I boot them again in few seconds, and I receive e "connection refused" error in the client. I always boot the server first, and the client after. Here's the code. DoLogin is an easy function with 2 read and 2 write. What's wrong in this code?

server.c

int main(){
    int ds_sock;
    struct sockaddr_in my_addr;
    ds_sock=socket(AF_INET,SOCK_STREAM,0);

    memset(&my_addr,0,sizeof(my_addr));
    my_addr.sin_family=AF_INET;
    my_addr.sin_port=htons(25000);
    my_addr.sin_addr.s_addr=INADDR_ANY;

    if(bind(ds_sock,(struct sockaddr *)&my_addr,sizeof(my_addr))<0){
        printf("Error in bind");
    }

    listen(ds_sock,2);
    int ds_sock_acc;
    struct sockaddr_in addr;
    size_t sin_size = sizeof(struct sockaddr_in);

    if((ds_sock_acc=accept(ds_sock,(struct sockaddr *)&addr,&sin_size))<1){
        printf("Error accept");
    }
    printf("Connected\n");
    char *usr = DoLogin(ds_sock_acc);
    printf("%s is connected\n",usr);

    close(ds_sock_acc);
    close(ds_sock);

    return 0;
}

client.c

int main(){
    int ds_sock;
    ds_sock = socket(AF_INET, SOCK_STREAM,0);

    int ret;
    struct sockaddr_in Eaddr;
    Eaddr.sin_family = AF_INET;
    Eaddr.sin_port = htons(25000);
    Eaddr.sin_addr.s_addr=inet_addr("127.0.0.1");
    ret = connect(ds_sock,(struct sockaddr *)&Eaddr,sizeof(Eaddr));
    if(ret==-1){ 
        printf("Error connect");
        perror("error:");
        exit(EXIT_FAILURE);
    }
    printf("Connect OK\n");
    char *usr = DoLogin(ds_sock);
    printf("Logged in as %s\n",usr);

    close(ds_sock);
    return 0;
}
testermaster
  • 1,031
  • 6
  • 21
  • 40
  • You have error checking there. Do you see any of the error messages in the server side? – Jonas Schäfer Oct 10 '14 at 10:30
  • 4
    He _should_ be seeing an error in the `bind()` call on the server side. – Alnitak Oct 10 '14 at 10:31
  • @alk not strictly a duplicate IMHO, because the OP didn't know that the ports get bound at all, whereas in the other question the OP knew this, but not how to fix it. – Alnitak Oct 10 '14 at 11:21

1 Answers1

3

The O/S usually prevents a listening socket from being recreated on the same port for a while after the previous socket has closed, to prevent messages originally destined for the original socket being delivered to the new one.

To override this behaviour you need setsockopt with the SO_REUSEADDR option (on the server side):

int optval = 1;
setsockopt(ds_sock, SO_REUSEADDR, &optval, sizeof(optval));

[error checking omitted]

Alnitak
  • 334,560
  • 70
  • 407
  • 495
  • I can fix this problem with some SIGNALs also? Also, I didn't had this problem for a while, it just started to happens few hours ago. Yesterday I tested many things and everything was fine with multiple try. – testermaster Oct 10 '14 at 10:43
  • signals won't affect the behaviour of the socket. The normal timeout involved between the O/S permits re-use of the same port without complaining should be less than four minutes – Alnitak Oct 10 '14 at 11:00
  • thanks for the reply. mm I've just downloaded another program, done by someone else. I've checked the entire code and there isn't any setsockopt, but if I close the server/client and I open it again in few seconds, it works fine. Also, I still don't get why yesterday I didn't had this problem with my code. Do you have any idea? – testermaster Oct 10 '14 at 11:09