1
votes

I would like to make program so that, when client disconnected, the server will back ready to accept a new request from client. Here is the code

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

#define MAXLINE 100
#define LISTENQ 10

int main()
{
    int tmp, listenfd, connfd;
    int sin_size;
    struct sockaddr_in servaddr, cliaddr;
    char  buff[MAXLINE];
    time_t ticks;
    while(true)
    {
        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family      = AF_INET;
        servaddr.sin_addr.s_addr = INADDR_ANY;
        servaddr.sin_port        = htons(13);
        memset(&(servaddr.sin_zero),'\0',8);
        listenfd = socket(AF_INET, SOCK_STREAM, 0);
        if(listenfd == -1){
           perror("error socket");
           exit(1);
          }

        tmp=bind(listenfd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr));
        if(tmp == -1){
            perror("error bind..");
            exit(1);
        }

        tmp=listen(listenfd, LISTENQ);
        if(tmp == -1){
            perror("error listen"); 
            exit(1);
        }

        sin_size = sizeof(struct sockaddr_in);    
        connfd=accept(listenfd,(struct sockaddr *)&cliaddr, &sin_size);
        if(connfd == -1){
            perror("error accept"); 
            exit(1);
        }

        ticks = time(NULL);
        snprintf(buff,sizeof(buff),"Now Time: %.24s\r\n", ctime(&ticks));
        write(connfd, buff, strlen(buff));
        close(connfd);
        close(listenfd);
    }
}

I found a problem on this part

tmp=bind(listenfd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr));

error: invalid conversion from 'int*' to 'socklen_t* {aka unsigned int*}' [-fpermissive]

connfd=accept(listenfd,(struct sockaddr *)&cliaddr, &sin_size);

error: initializing argument 3 of 'int accept(int, sockaddr*, socklen_t*)' [-fpermissive]

What should I do with those problem? Didn't the pointer right?

4
That's a pretty comprehensible error message. - Geoffroy
declare sin_size as socklen_t. also, remember to #include <stdbool.h> - user4815162342
@user4815162342 do you mean declare sin_size as socklen_t like this "int sin_size socklen_t" ? - greenthunder
@greenthunder change line 16 to socklen_t sin_size; should be ok and that's all. - A Lan
Small things: bzero is deprecated, use memset. Don't use for example sockaddr_in, use sockaddr_storage (etc) to make life easier for yourself or other people when the need for IPv6 gets real. - Jite

4 Answers

1
votes

You need to use

socklen_t sin_size;
1
votes

Chnage your declaration

 socklen_t  sin_size;  

This solves your issue.


you can also Try this as last resort but above change would works fine for you.

Modify this statement

connfd=accept(listenfd,(struct sockaddr *)&cliaddr,(socklen_t * ) &sin_size);

See man accept

After seeing @alk comment i am adding this part from comment.

Especially when casting pointers, it might just cast away an compile-time error but very well might crash when running as the sizes of what the program expects when Dereferencing the pointer differs from reality.

0
votes

Use while(1) instead of while(true) and use a C-compiler instead of a C++-compiler.

The errors come from compiling the source code with a C++compiler. If you use a C-Compiler your code does not produce the mentioned errors, except that now true is not defined.

0
votes

Correct answer, need to run on root-access user

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>

#define MAXLINE 100
#define LISTENQ 10

int main()
{
    int tmp, listenfd, connfd;
    socklen_t sin_size;
    struct sockaddr_in servaddr, cliaddr;
    char  buff[MAXLINE];
    time_t ticks;
    while(true)
    {
        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family      = AF_INET;
        servaddr.sin_addr.s_addr = INADDR_ANY;
        servaddr.sin_port        = htons(13);
        memset(&(servaddr.sin_zero),'\0',8);
        listenfd = socket(AF_INET, SOCK_STREAM, 0);
        if(listenfd == -1){
           perror("error socket");
           exit(1);
          }

        tmp=bind(listenfd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr));
        if(tmp == -1){
            perror("error bind..");
            exit(1);
        }

        tmp=listen(listenfd, LISTENQ);
        if(tmp == -1){
            perror("error listen"); 
            exit(1);
        }

        sin_size = sizeof(struct sockaddr_in);    
        connfd=accept(listenfd,(struct sockaddr *)&cliaddr, &sin_size);
        if(connfd == -1){
            perror("error accept"); 
            exit(1);
        }

        ticks = time(NULL);
        snprintf(buff,sizeof(buff),"Sekarang pukul: %.24s\r\n", ctime(&ticks));
        write(connfd, buff, strlen(buff));
        close(connfd);
        close(listenfd);
    }
}