Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <arpa/inet.h>
- #include <pthread.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/socket.h>
- #include <sys/types.h>
- #include <unistd.h>
- #define MAX_LEN 1024
- #define NAME_LEN 20
- #define MAX_USERS 10
- #define USERS_FILE "users.txt"
- #define CONN "CONN"
- #define LIST "LIST"
- #define EXIT "EXIT"
- #define HELO "HELO"
- #define MESG "MESG"
- #define CURR "CURR"
- #define ERR "ERR"
- #define OK "200 OK"
- #define NOT_FOUND "file not found"
- #define AVAILABLE "201 AVAILABLE"
- #define ASK_NAME "What is your name?"
- extern void fatal_error(char *msg);
- extern void clear_line();
- extern void server(int port);
- extern void *handle_client(void *param);
- extern int send_to(int sock, char *send_buff);
- extern int receive_front(int sock, char *recv_buff);
- extern int parse(char *tag, char *buffer, char *name);
- extern void update_file(int i, char *mesg);
- struct client_info
- {
- pthread_t tid;
- int sockfd;
- int new_sock;
- char name[MAX_LEN];
- char ip[INET_ADDRSTRLEN];
- int port;
- struct sockaddr_in addr;
- };
- struct client_info clients[2];
- pthread_mutex_t file_mutex;
- int parse(char *tag, char *buffer, char *remaining)
- {
- char buffer_copy[MAX_LEN];
- strcpy(buffer_copy, buffer);
- char *tok = strtok(buffer_copy, " ");
- if (tok == NULL)
- return -1;
- if (strcmp(tok, tag) != 0)
- return -1;
- // copy the rest of the message ahead to the "remaining" pointer
- strcpy(remaining, buffer + strlen(tag) + 1);
- return 0;
- }
- void fatal_error(char *msg)
- {
- perror(msg);
- exit(1);
- }
- int send_to(int sock, char *send_buff)
- {
- int send_len = strlen(send_buff);
- int bytes_sent = send(sock, send_buff, send_len + 1, 0);
- if (bytes_sent < 0)
- fatal_error("send error\n");
- return bytes_sent;
- }
- int receive_from(int sock, char *recv_buff)
- {
- while (1)
- {
- int bytes_received = recv(sock, recv_buff, MAX_LEN, 0);
- if (bytes_received < 0)
- fatal_error("receive error\n");
- if (bytes_received == 0)
- continue;
- return bytes_received;
- }
- }
- void clear_line()
- {
- printf("\033[2K"); // clear entire line
- printf("\r"); // move cursor to beginning of line
- }
- int main(int argc, char **argv)
- {
- if (argc != 1)
- printf("Usage: <port>\n");
- int port = atoi(argv[1]);
- server(port);
- return 0;
- }
- void server(int port)
- {
- FILE *fp = fopen("clientid1_clientid2.txt", "w");
- fclose(fp);
- printf("<< Starting server session >>\n");
- struct sockaddr_in my_addr;
- my_addr.sin_family = AF_INET;
- my_addr.sin_port = htons(port);
- // my_addr sin_addr s_addr = htoml(INADDR_ANY);
- inet_pton(AF_INET, "127.0.0.1", &my_addr.sin_addr);
- int sockfd = socket(AF_INET, SOCK_STREAM, 0);
- if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)) < 0)
- fatal_error("setsockopt(SO_REUSEADDR) failed");
- if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr)) == -1)
- fatal_error("bind() failed");
- printf(" << bind successful >>\n");
- if (listen(sockfd, 0) == -1)
- fatal_error("listen() failed");
- printf("server listening on port %d>>\n", port);
- for (int i = 0; i < 2; i++)
- {
- clients[i].sockfd = sockfd;
- clients[i].new_sock = -1;
- int *id = (int *)malloc(sizeof(int));
- *id = i;
- pthread_create(&clients[i].tid, NULL, handle_client, (void *)id);
- }
- for (int i = 0; i < MAX_USERS; i++)
- pthread_join(clients[i].tid, NULL);
- printf("closing server");
- }
- void *handle_client(void *param)
- {
- char recv_buff[MAX_LEN];
- char send_buff[MAX_LEN];
- int client_num = *(int *)param;
- free(param);
- struct client_info *client = &clients[client_num];
- int sockfd = client->sockfd;
- char *name = client->name;
- socklen_t slen = sizeof(client->addr);
- int new_socket = accept(sockfd, (struct sockaddr *)&client->addr, &slen);
- client->new_sock = new_socket;
- if (new_socket < 0)
- fatal_error("accept() failed");
- if (client_num == MAX_USERS - 1)
- {
- printf("<< final client connected, not accepting any more connections >>\n");
- close(new_socket);
- }
- inet_ntop(AF_INET, &client->addr.sin_addr, client->ip, INET_ADDRSTRLEN);
- client->port = ntohs(client->addr.sin_port);
- printf("<< client %d connected from %s:%d >>\n", client_num + 1, client->ip, client->port);
- int bytes_received = receive_from(new_socket, recv_buff);
- printf("[CLIENT-%d @ SERVER] [%d bytes]\t: %s\n", client_num + 1, bytes_received, recv_buff);
- if (strcmp(recv_buff, HELO) != 0)
- fatal_error("client did not send HELO as the first message");
- memset(send_buff, 0, MAX_LEN);
- sprintf(send_buff, "%s %s", MESG, ASK_NAME);
- int bytes_sent = send_to(new_socket, send_buff);
- printf("[Server @ CLIENT-%d] [%d bytes]\t: %s\n", client_num + 1, bytes_sent, send_buff);
- bytes_received = receive_from(new_socket, recv_buff);
- if (parse(MESG, recv_buff, name) != 0)
- fatal_error("client did not send NAME in appropriate format");
- printf("name : %s\n", name);
- printf("[CLIENT-%d @ SERVER] [%d bytes]\t: %s\n", client_num + 1, bytes_received, recv_buff);
- // update_file();
- while (1)
- {
- bytes_received = receive_from(client->new_sock, recv_buff);
- printf("[%s @ SERVER] [%d bytes]\t: %s\n", name, bytes_received, recv_buff);
- char message[MAX_LEN];
- int *chat = 0;
- parse(MESG, recv_buff, message);
- char sendMesg[MAX_LEN];
- strcpy(sendMesg, MESG);
- strncat(sendMesg, " ", 1);
- strncat(sendMesg, name, strlen(name));
- strncat(sendMesg, " ", 1);
- strncat(sendMesg, message, strlen(message));
- strcpy(send_buff, sendMesg);
- // strncat(send_buff, " ", 1);
- // strcat(send_buff, " ");
- // strcat(send_buff, clients[1 - client_num].name);
- int bytes_sent = send_to(clients[1 - client_num].new_sock, send_buff);
- // int bytes_sent = send_to(client->new_sock, send_buff);
- printf("[SERVER @ %s] [%d bytes]\t: %s\n", name, bytes_sent, recv_buff);
- update_file(client_num, message);
- if (strcmp(message, EXIT) == 0)
- {
- printf("<< %s has left the chat >>\n", name);
- send_to(clients[client_num].new_sock, send_buff);
- break;
- }
- }
- close(client->new_sock);
- pthread_exit(NULL);
- }
- void update_file(int i, char message[MAX_LEN])
- {
- pthread_mutex_lock(&file_mutex);
- FILE *fp = fopen("clientid1_clientid2.txt", "a+");
- if (fp == NULL)
- fatal_error("fopen() failed");
- printf("updating file\n");
- fprintf(fp, "%s: ", clients[i].name);
- fprintf(fp, "%s", message);
- fprintf(fp, "\n");
- fclose(fp);
- pthread_mutex_unlock(&file_mutex);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement