UNIX & GNU/Linux - System calls - Using accept()
The accept() system call waits a connection from a client. For the example above, we are going to take the nc tool (you can use telnet, it is the same). If we reach the server through the nc connection, the server will shutdown. But that’s what we want to do. Let’s see it in this accept() tutorial. Using accept() server.c /* server.c */ #include #include #include #include #include #include #include #include #include "h.h" void my_socket(t_s *s) { s->name = "TCP"; s->domain = AF_INET; s->type = SOCK_STREAM; s->pe = getprotobyname(s->name); s->fd = socket(s->domain, s->type, s->pe->p_proto); check_error(s->fd, -1); } void my_bind(t_s *s, int port) { s->sockfd = s->fd; s->addr.sin_family = s->domain; s->addr.sin_addr.s_addr = INADDR_ANY; s->addr.sin_port = htons(port); s->addrlen = sizeof(s->addr); s->bindValue = bind(s->fd, (const struct sockaddr *)&s->addr, s->addrlen); check_error(s->bindValue, -1); } void my_listen(t_s *s, int backlog) { s->listenValue = listen(s->sockfd, backlog); check_error(s->listenValue, -1); } void my_accept(t_s *s) { s->addrlenAccept = sizeof(s->addrAccept); s->acceptValue = accept(s->sockfd, (struct sockaddr *)&s->addrAccept, &s->addrlenAccept); check_error(s->acceptValue, -1); } int main(int ac, char *av[]) { t_s s; check_arg(ac, ARG_SIZE); my_socket(&s); my_bind(&s, atoi(av[1])); my_listen(&s, BACKLOG); my_accept(&s); debug(&s); check_error(close(s.acceptValue), -1); check_error(close(s.fd), -1); return 0; } debug.c /* debug.c */ #include #include #include #include #include #include "h.h" void debug(t_s *s) { printf("\n===== socket() =====\n"); printf("domain = %d\n", s->domain); printf("type = %d\n", s->type); printf("fd = %d\n", s->fd); printf("name = %s\n", s->name); printf("p_proto = %d\n", s->pe->p_proto); printf("\n===== bind() =====\n"); printf("sockfd = %d\n", s->sockfd); printf("sin_family = %d\n", s->addr.sin_family); printf("sin_addr.s_addr = %d\n", s->addr.sin_addr.s_addr); printf("sin_port = %d\n", s->addr.sin_port); printf("addrlen = %d\n", s->addrlen); printf("bindValue = %d\n", s->bindValue); printf("\n===== listen() =====\n"); printf("listenValue = %d\n", s->listenValue); printf("\n===== accept() =====\n"); printf("addrlenAccept = %d\n", s->addrlenAccept); printf("acceptValue = %d\n\n", s->acceptValue); } void check_error(int test, int error) { if (test == error) { fprintf(stderr, "ERROR: %s\n", strerror(errno)); exit(EXIT_FAILURE); } } void check_arg(int ac, int number) { if (ac < number) { printf("Usage: ./server [PORT]\n"); exit(EXIT_FAILURE); } } h.h #ifndef H_H_ #define H_H_ #include /** * Define */ #define ARG_SIZE 2 #define BACKLOG 10 #define BUF_SIZE 255 /** * Structure */ typedef struct mystruct { /* socket */ int domain; int type; int fd; char *name; struct protoent *pe; /* bind */ int sockfd; socklen_t addrlen; struct sockaddr_in addr; int bindValue; /* listen */ int listenValue; /* accept */ int acceptValue; socklen_t addrlenAccept; struct sockaddr_in addrAccept; } t_s; /** * Prototype */ void debug(t_s *); void check_error(int, int); void check_arg(int, int); #endif /* H_H_ */ Compiling $ gcc server.c debug.c -o server ; ./server 5000 Now that the server is launched, it’s waiting a connection from a client on the port 5000. ...