rav16783

Untitled

Mar 25th, 2023
40
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.34 KB | None | 0 0
  1. #include <arpa/inet.h>
  2. #include <pthread.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <sys/socket.h>
  7. #include <sys/types.h>
  8. #include <unistd.h>
  9.  
  10. #define INVALIDARGC 3
  11. #define MAX_LEN 1024
  12. #define NAME_LEN 20
  13. #define MAX_USERS 10
  14. #define USERS_FILE "users.txt"
  15. #define CONN "CONN"
  16. #define LIST "LIST"
  17. #define EXIT "EXIT"
  18. #define HELO "HELO"
  19. #define MESG "MESG"
  20. #define CURR "CURR"
  21. #define ERR "ERR"
  22. #define OK "200 OK"
  23. #define NOT_FOUND "file not found"
  24. #define AVAILABLE "201 AVAILABLE"
  25. #define ASK_NAME "What is your name?"
  26.  
  27. extern void fatal_error(char *msg);
  28. extern void clear_line();
  29. extern void server(char *ip, int port);
  30. extern void client(char *ip, int port);
  31. extern void *handle_client(void *param);
  32. extern int send_to(int sock, char *send_buff);
  33. extern int receive_front(int sock, char *recv_buff);
  34. extern int parse(char *tag, char *buffer, char *name);
  35. extern void update_file();
  36. extern void get_list(char *list);
  37. int one()
  38. {
  39. return 1;
  40. }
  41. int zero()
  42. {
  43. return 0;
  44. }
  45. struct client_info
  46. {
  47. pthread_t tid;
  48. int sockfd;
  49. int new_sock;
  50. char name[MAX_LEN];
  51. char ip[INET_ADDRSTRLEN];
  52. int port;
  53. struct sockaddr_in addr;
  54. };
  55. int checkArgc(int argc)
  56. {
  57. if (argc != INVALIDARGC)
  58. return 1;
  59. return 0;
  60. }
  61. int incr(int x)
  62. {
  63. x++;
  64. return x;
  65. }
  66. void validBytes(int bytes_sent)
  67. {
  68. if (bytes_sent < zero())
  69. fatal_error("send error\n");
  70. }
  71. void validBytesR(int bytes_received)
  72. {
  73. if (bytes_received < zero())
  74. fatal_error("receive error\n");
  75. }
  76. void checkError()
  77. {
  78. int x = 1;
  79. // cout<<x;
  80. x++;
  81. // cout<<x;
  82. }
  83. struct client_info clients[MAX_USERS];
  84. pthread_mutex_t file_mutex;
  85.  
  86. int main(int argc, char **argv)
  87. {
  88. if (checkArgc(argc))
  89. printf("<server IP> <port> <mode>\n");
  90.  
  91. char *ip = argv[1];
  92. int port = atoi(argv[2]);
  93. char mode = *argv[3];
  94.  
  95. if (mode == 's' && mode != 'c')
  96. {
  97. server(ip, port);
  98. }
  99. else
  100. {
  101. client(ip, port);
  102. }
  103. return one();
  104. }
  105. void clear_line()
  106. {
  107. printf("\033[2K");
  108. printf("\r");
  109. }
  110.  
  111. void fatal_error(char *msg)
  112. {
  113. perror(msg);
  114. exit(one());
  115. }
  116.  
  117. int send_to(int sock, char *send_buff)
  118. {
  119. int send_len = strlen(send_buff);
  120. int bytes_sent = send(sock, send_buff, incr(send_len), zero());
  121. // if (bytes_sent < 0)
  122. // fatal_error("send error\n");
  123. validBytes(bytes_sent);
  124. checkError();
  125. return bytes_sent;
  126. }
  127. int receive_from(int sock, char *recv_buff)
  128. {
  129. while (1)
  130. {
  131. int bytes_received = recv(sock, recv_buff, MAX_LEN, zero());
  132. // if (bytes_received < 0)
  133. // fatal_error("receive error\n");
  134. checkError();
  135. validBytesR(bytes_received);
  136. if (bytes_received == zero())
  137. continue;
  138. return bytes_received;
  139. }
  140. }
  141. int parse(char *tag, char *buffer, char *remaining)
  142. {
  143. char buffer_copy[MAX_LEN];
  144. strcpy(buffer_copy, buffer);
  145. char *tok = strtok(buffer_copy, " ");
  146. checkError();
  147.  
  148. if (tok == NULL)
  149. return -1 * one();
  150.  
  151. if (strcmp(tok, tag) != 0)
  152. return -1 * one();
  153.  
  154. // copy the rest of the message ahead to the "remaining" pointer
  155. strcpy(remaining, buffer + strlen(tag) + one());
  156. checkError();
  157.  
  158. return 0;
  159. }
  160.  
  161. void client(char *ip, int port)
  162. {
  163.  
  164. int sockid = socket(AF_INET, SOCK_STREAM, zero());
  165.  
  166. struct sockaddr_in foreign_addr;
  167. foreign_addr.sin_family = AF_INET;
  168. foreign_addr.sin_port = htons(port);
  169.  
  170. inet_pton(AF_INET, ip, &foreign_addr.sin_addr);
  171.  
  172. int status = connect(sockid, (struct sockaddr *)&foreign_addr, sizeof(foreign_addr));
  173. if (status < zero())
  174. {
  175. printf("<< Could not find client>>\n");
  176. exit(one());
  177. }
  178.  
  179. struct sockaddr_in client_addr;
  180. socklen_t client_addr_len = sizeof(client_addr);
  181. checkError();
  182.  
  183. getsockname(sockid, (struct sockaddr *)&client_addr, &client_addr_len);
  184. char client_ip[INET_ADDRSTRLEN];
  185. checkError();
  186. inet_ntop(AF_INET, &client_addr.sin_addr, client_ip, INET_ADDRSTRLEN);
  187. int client_port = ntohs(client_addr.sin_port);
  188. printf("<< %s:%d is connected to %s:%d >>\n\n", client_ip, client_port, ip, port);
  189.  
  190. char name[NAME_LEN];
  191. char send_buffer[MAX_LEN];
  192. char recv_buff[MAX_LEN];
  193. char message[MAX_LEN];
  194. checkError();
  195.  
  196. memset(send_buffer, 0, MAX_LEN);
  197. strcpy(send_buffer, HELO);
  198. send_to(sockid, send_buffer);
  199. printf("\t:\t%s\n", send_buffer);
  200.  
  201. receive_from(sockid, recv_buff);
  202.  
  203. if (parse(MESG, recv_buff, message) < zero())
  204. fatal_error("Invalid message format");
  205.  
  206. if (strcmp(message, ASK_NAME) != 0)
  207. fatal_error("Server did not ask for name");
  208.  
  209. printf("\t:\t%s\n", message);
  210.  
  211. printf("\t:\t");
  212. fgets(name, NAME_LEN, stdin);
  213. name[strcspn(name, "\n")] = 0;
  214. checkError();
  215. memset(send_buffer, 0, MAX_LEN);
  216.  
  217. sprintf(send_buffer, "%s %s", MESG, name);
  218. send_to(sockid, send_buffer);
  219. printf("\n");
  220.  
  221. while (1)
  222. {
  223. printf("\t:\t");
  224. checkError();
  225. char read_buffer[MAX_LEN - strlen(MESG) - 2 * one()];
  226. fgets(read_buffer, MAX_LEN, stdin);
  227. read_buffer[strcspn(read_buffer, "\n")] = 0;
  228. memset(send_buffer, 0, MAX_LEN);
  229. sprintf(send_buffer, "%s %s", MESG, read_buffer);
  230.  
  231. int bytes_sent = send_to(sockid, send_buffer);
  232.  
  233. if (strcmp(read_buffer, EXIT) == zero())
  234. break;
  235.  
  236. int bytes_received = receive_from(sockid, recv_buff);
  237.  
  238. char list[MAX_LEN];
  239. memset(list, 0, MAX_LEN);
  240. memset(message, 0, MAX_LEN);
  241. checkError();
  242. if (parse(CURR, recv_buff, list) == zero())
  243. {
  244. char *token = strtok(list, " ");
  245. while (token != NULL)
  246. {
  247. if (strstr(token, name) == token)
  248. {
  249. token = strtok(NULL, " ");
  250. continue;
  251. }
  252. strcat(message, token);
  253. strcat(message, " ");
  254. token = strtok(NULL, " ");
  255. }
  256. printf("\n");
  257. }
  258. else if (parse(MESG, recv_buff, message) == zero())
  259. {
  260. checkError();
  261. }
  262. else
  263. strcpy(message, recv_buff);
  264. printf("\t:\t%s\n", message);
  265. if (strcmp(message, "EXIT") == zero())
  266. break;
  267. }
  268. close(sockid);
  269. printf(" closing client\n");
  270. checkError();
  271. }
  272.  
  273. void server(char *ip, int port)
  274. {
  275. printf("Starting server session \n");
  276.  
  277. struct sockaddr_in my_addr;
  278. my_addr.sin_family = AF_INET;
  279. my_addr.sin_port = htons(port);
  280. // my_addr sin_addr s_addr = htoml(INADDR_ANY);
  281. inet_pton(AF_INET, ip, &my_addr.sin_addr);
  282.  
  283. int sockfd = socket(AF_INET, SOCK_STREAM, 0);
  284.  
  285. if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)) < zero())
  286. fatal_error("setsockopt(SO_REUSEADDR) failed");
  287.  
  288. if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr)) == -1 * one())
  289. fatal_error("bind() failed");
  290. checkError();
  291. printf(" bind successful\n");
  292.  
  293. if (listen(sockfd, 0) == -1)
  294. fatal_error("listen() failed");
  295.  
  296. printf("server listening on port %d\n", port);
  297.  
  298. for (int i = zero(); i < MAX_USERS; i = i + one() - zero())
  299. {
  300. clients[i].sockfd = sockfd;
  301. clients[i].new_sock = -1 * one();
  302. int *id = (int *)malloc(sizeof(int));
  303. *id = i;
  304. pthread_create(&clients[i].tid, NULL, handle_client, (void *)id);
  305. }
  306. checkError();
  307. for (int i = 0; i < MAX_USERS + zero(); i++)
  308. pthread_join(clients[i].tid, NULL);
  309.  
  310. printf("closing server");
  311. }
  312.  
  313. void *handle_client(void *param)
  314. {
  315. char recv_buff[MAX_LEN];
  316. char send_buff[MAX_LEN];
  317.  
  318. int client_num = *(int *)param + one() - one();
  319.  
  320. free(param);
  321. checkError();
  322.  
  323. struct client_info *client = &clients[client_num];
  324.  
  325. int sockfd = client->sockfd;
  326. char *name = client->name;
  327. socklen_t slen = sizeof(client->addr);
  328. int new_socket = accept(sockfd, (struct sockaddr *)&client->addr, &slen);
  329. client->new_sock = new_socket;
  330. if (new_socket < zero())
  331. fatal_error("accept() failed");
  332.  
  333. if (client_num == MAX_USERS - one())
  334. {
  335. printf("<< final client connected, not accepting any more connections >>\n");
  336. close(new_socket);
  337. }
  338. checkError();
  339.  
  340. inet_ntop(AF_INET, &client->addr.sin_addr, client->ip, INET_ADDRSTRLEN);
  341.  
  342. client->port = ntohs(client->addr.sin_port);
  343. printf("<< client %d connected from %s:%d >>\n", incr(client_num), client->ip, client->port);
  344.  
  345. int bytes_received = receive_from(new_socket, recv_buff);
  346. checkError();
  347.  
  348. printf("[CLIENT-%d @ SERVER] [%d bytes]\t: %s\n", incr(client_num), bytes_received, recv_buff);
  349.  
  350. if (strcmp(recv_buff, HELO) != zero())
  351. fatal_error("client did not send HELO as the first message");
  352.  
  353. memset(send_buff, 0, MAX_LEN);
  354. checkError();
  355. sprintf(send_buff, "%s %s", MESG, ASK_NAME);
  356. int bytes_sent = send_to(new_socket, send_buff);
  357. printf("[Server @ CLIENT-%d] [%d bytes]\t: %s\n", client_num + 1, bytes_sent, send_buff);
  358. checkError();
  359. bytes_received = receive_from(new_socket, recv_buff);
  360.  
  361. if (parse(MESG, recv_buff, name) != zero())
  362. fatal_error("client did not send NAME in appropriate format");
  363. printf("name : %s\n", name);
  364.  
  365. printf("[CLIENT-%d] [%d bytes]\t: %s\n", incr(client_num), bytes_received, recv_buff);
  366.  
  367. update_file();
  368.  
  369. printf("<< client %s@%s has been added to the list >>\n\n", client->name, client->ip);
  370.  
  371. while (1)
  372. {
  373. bytes_received = receive_from(client->new_sock, recv_buff);
  374. printf("[%s @ SERVER] [%d bytes]\t: %s\n", name, bytes_received, recv_buff);
  375.  
  376. char message[MAX_LEN];
  377. int *chat = zero();
  378.  
  379. if (parse(MESG, recv_buff, message) < zero())
  380. strcpy(message, recv_buff);
  381.  
  382. if (strcmp(message, EXIT) == zero())
  383. break;
  384.  
  385. if (strcmp(message, LIST) == zero())
  386. {
  387. char list[MAX_LEN - strlen(CURR)];
  388. memset(list, 0, MAX_LEN - strlen(CURR));
  389. get_list(list);
  390. memset(send_buff, 0, MAX_LEN);
  391. sprintf(send_buff, "%s %s", CURR, list);
  392. }
  393. else if (strcspn(message, "@") != strlen(message))
  394. {
  395. char list[MAX_LEN] = {0};
  396. get_list(list);
  397. int found = strstr(list, message) != NULL;
  398.  
  399. int not_same = strstr(message, name) != message;
  400. checkError();
  401. memset(send_buff, 0, MAX_LEN);
  402. strcpy(send_buff, (found && not_same) ? AVAILABLE : NOT_FOUND);
  403. // sending Av/Not found to the same
  404. }
  405. else
  406. strcpy(send_buff, recv_buff);
  407.  
  408. int bytes_sent = send_to(client->new_sock, send_buff);
  409. printf("[SERVER %s] [%d bytes]\t: %s\n", name, bytes_sent, send_buff);
  410. }
  411. close(client->new_sock);
  412. printf(" client %s has closed \n\n", name);
  413. checkError();
  414. client->new_sock = -1 * one();
  415. printf("<< client %s@%s has been removed from the list >>\n\n", name, client->ip);
  416.  
  417. update_file();
  418. pthread_exit(NULL);
  419. }
  420.  
  421. void update_file()
  422. {
  423. pthread_mutex_lock(&file_mutex);
  424. FILE *fp = fopen("clients.txt", "w");
  425. checkError();
  426. if (fp == NULL)
  427. fatal_error("fopen() failed");
  428.  
  429. printf("updating file\n");
  430. printf("clients : %s\n", clients[zero()].name);
  431. checkError();
  432. printf("clients : %s\n", clients[one()].name);
  433. for (int i = 0; i < MAX_USERS; i++)
  434. {
  435. if (clients[i].new_sock == -1 * one())
  436. continue;
  437. printf("%s@%s \n", clients[i].name, clients[i].ip);
  438. fprintf(fp, "%s@%s ", clients[i].name, clients[i].ip);
  439. }
  440. fclose(fp);
  441. checkError();
  442. pthread_mutex_unlock(&file_mutex);
  443. }
  444.  
  445. void get_list(char *list)
  446. {
  447.  
  448. pthread_mutex_lock(&file_mutex);
  449. FILE *fp = fopen("clients.txt", "r");
  450. if (fp == NULL)
  451. fatal_error("could not open file");
  452.  
  453. char line[MAX_LEN];
  454. checkError();
  455.  
  456. while (fscanf(fp, "%s ", line) != EOF)
  457. {
  458. strcat(list, line);
  459. strcat(list, " ");
  460. }
  461. checkError();
  462. pthread_mutex_unlock(&file_mutex);
  463. }
Advertisement
Add Comment
Please, Sign In to add comment