Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- This application listeners for socket connections, data sent to the socket will be reversed and
- sent back to the sender of the data, the socket connection will be closed
- */
- #include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <pthread.h>
- #include <sys/socket.h>
- #include <sys/un.h>
- #include <sys/types.h>
- #define MAX_CLIENTS 10
- #define BUFFER_SIZE 8192
- // Prototypes
- void * handle_client_sock(void * arg);
- char * strrev(const char * data, size_t len);
- // Constants
- const char * socket_file = "/tmp/reverser.sock";
- // Global variables
- static int next_idx = 0;
- static int client_sockfds[MAX_CLIENTS];
- static struct sockaddr_un client_addresses[MAX_CLIENTS];
- int main()
- {
- int res;
- int serv_sockfd;
- int server_len;
- socklen_t client_len;
- struct sockaddr_un server_address;
- pthread_t cli_threads[MAX_CLIENTS];
- pthread_attr_t thread_attr;
- unlink(socket_file);
- serv_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
- server_address.sun_family = AF_UNIX;
- strcpy(server_address.sun_path, socket_file);
- server_len = sizeof(server_address);
- bind(serv_sockfd, (struct sockaddr *) &server_address, server_len);
- // Initialize detached thread attributes
- res = pthread_attr_init(&thread_attr);
- if (res) {
- perror("Attributes");
- return 1;
- }
- res = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
- if (res) {
- perror("detached attr set");
- return 1;
- }
- listen(serv_sockfd, 5);
- for (;;) {
- int id_to_pass = next_idx;
- puts("Server waiting...");
- if (id_to_pass >= MAX_CLIENTS) {
- puts("Max threads reached");
- break;
- }
- client_len = sizeof(client_addresses[0]);
- client_sockfds[id_to_pass] = accept(serv_sockfd,
- (struct sockaddr *) &client_addresses[id_to_pass],
- &client_len);
- if (client_sockfds[id_to_pass] == -1) {
- puts("invalid fd");
- continue;
- }
- pthread_create(&cli_threads[id_to_pass], &thread_attr, handle_client_sock, (void * ) &id_to_pass);
- ++next_idx;
- }
- pthread_attr_destroy(&thread_attr);
- // First wait for threads ..
- for (;;) {
- puts("Waiting for threads to stop");
- if (! next_idx) break;
- sleep(5);
- }
- close(serv_sockfd);
- unlink(socket_file);
- return 0;
- }
- void * handle_client_sock(void * arg)
- {
- // Handle the socket
- char buffer[BUFFER_SIZE];
- int sock_id = *(int *) arg;
- size_t b_read;
- printf("Thread num %d\n", sock_id);
- printf("Handling socket id: %d\n", client_sockfds[sock_id]);
- // Read some data from the socket
- b_read = read(client_sockfds[sock_id], buffer, BUFFER_SIZE);
- printf("Bytes read: %d\n", (int) b_read);
- // Reverse the string
- char * reversed = strrev(buffer, b_read);
- printf("Reversed: %s\n", reversed);
- write(client_sockfds[sock_id], reversed, b_read);
- close(client_sockfds[sock_id]);
- // Lower the next, if not equal to zero
- --next_idx;
- // Free resources
- free(reversed);
- // Exit succesfully
- puts("Stopping thread");
- pthread_exit(0);
- }
- char * strrev(const char * data, size_t len)
- {
- char * dest = (char*) malloc(len + 1);
- const char * last = data + (len - 1);
- for (char * dptr = dest; last >= data; ++dptr, --last)
- *dptr = *last;
- *(dest + len) = '\0';
- return dest;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement