Advertisement
Guest User

selectechoserver.c

a guest
Apr 24th, 2017
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.91 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <errno.h>
  6. #include <sys/types.h>
  7. #include <sys/socket.h>
  8. #include <sys/time.h>
  9. #include <netinet/in.h>
  10. #include <sys/select.h>
  11.  
  12. #define QLEN 5
  13. #define BUFSIZE 2048
  14. typedef int bool;
  15. #define true 1
  16. #define false 0
  17.  
  18. int passivesock( char *service, char *protocol, int qlen, int *rport );
  19.  
  20. /*
  21. ** The server ...
  22. ** YOU MAY WANT TO VISIT MY REPO FOR THIS PROJECT (GITHUB):
  23. ** https://github.com/ardulat/Operating-Systems
  24. */
  25.  
  26. struct Client {
  27. int fd;
  28. bool all;
  29. struct Tag* tag;
  30. struct Client* next;
  31. };
  32.  
  33. struct Tag {
  34. char* tagName;
  35. struct Tag* next;
  36. };
  37.  
  38. struct Read {
  39. int fd;
  40. int cc;
  41. char *original;
  42. };
  43.  
  44. struct Write {
  45. int fd;
  46. int cc;
  47. long size;
  48. char *ibuffer;
  49. char *send;
  50. };
  51.  
  52. struct Client* users;
  53. int usersCount;
  54. int nfds;
  55. fd_set afds;
  56. fd_set rfds;
  57.  
  58. void printUsers() {
  59. struct Client* temp = users;
  60. printf("%d users online:\n", usersCount);
  61. while(temp != NULL) {
  62. printf("User%d\n", temp->fd);
  63. temp = temp->next;
  64. }
  65. printf("\n");
  66. }
  67.  
  68. void insertTag(int fd, char* tagName) {
  69. struct Tag* temp = (struct Tag*) malloc (sizeof(struct Tag*));
  70. struct Client* user = users;
  71. int i;
  72. for(i = 0; i < usersCount; i++) {
  73. if(user->fd == fd) {
  74. temp->tagName = tagName;
  75. temp->next = user->tag;
  76. user->tag = temp;
  77. break;
  78. }
  79. user = user->next;
  80. }
  81. }
  82.  
  83. void deleteTag(int fd, char* tagName) {
  84. struct Tag* temp = (struct Tag*) malloc (sizeof(struct Tag*));
  85. struct Client* user = users;
  86. int i;
  87. for(i = 0; i < usersCount; i++) {
  88. if(user->fd == fd && user->tag != NULL) {
  89. temp = user->tag;
  90. if(temp->next == NULL) {
  91. user->tag = temp->next; // = NULL
  92. free(temp);
  93. return;
  94. }
  95. struct Tag* temp1 = temp->next;
  96. while(temp != NULL) {
  97. if(strcmp(temp1->tagName, tagName) == 0) {
  98. temp->next = temp1->next;
  99. free(temp1);
  100. break;
  101. }
  102. temp = temp->next;
  103. temp1 = temp->next;
  104. }
  105. break;
  106. }
  107. user = user->next;
  108. }
  109. }
  110.  
  111. void registerUser(int fd) {
  112. struct Client* temp = users;
  113. int i;
  114. for (i = 0; i < usersCount; i++) {
  115. if (temp->fd == fd) {
  116. temp->all = true;
  117. }
  118. // register all tags to this user (fd)
  119. struct Tag* tag = temp->tag;
  120. if(tag != NULL) {
  121. while(tag != NULL) {
  122. insertTag(fd, tag->tagName);
  123. tag = tag->next;
  124. }
  125. }
  126. temp = temp->next;
  127. }
  128. }
  129.  
  130. void deregisterUser(int fd) {
  131. struct Client* temp = users;
  132. int i;
  133. for (i = 0; i < usersCount; i++) {
  134. if (temp->fd == fd) {
  135. temp->all = false;
  136. }
  137. // deregister all tags to this user (fd)
  138. struct Tag* tag = temp->tag;
  139. if(tag != NULL) {
  140. while(tag != NULL) {
  141. deleteTag(fd, tag->tagName);
  142. tag = tag->next;
  143. }
  144. }
  145. temp = temp->next;
  146. }
  147. }
  148.  
  149. // function for checking tags for particular fd
  150. void printTags(int fd) {
  151. struct Client* user = users;
  152. int i;
  153. printf("User%d has tags:\n", fd);
  154. for(i = 0; i < usersCount; i++) {
  155. if(user->fd == fd) {
  156. struct Tag* temp = user->tag;
  157. while(temp != NULL) {
  158. printf("--%s--\n", temp->tagName);
  159. temp = temp->next;
  160. }
  161. break;
  162. }
  163. user = user->next;
  164. }
  165. }
  166.  
  167. pthread_mutex_t *mutexes;
  168.  
  169. void *writeThread(void *ign) {
  170. struct Write arg = *((struct Write *) ign);
  171. int fd = arg.fd;
  172. int cc = arg.cc;
  173. long size = arg.size;
  174. char *send = arg.send;
  175. char *ibuffer = arg.ibuffer;
  176.  
  177. pthread_mutex_lock(&mutexes[fd]);
  178.  
  179. write(fd, send, cc);
  180. write(fd, ibuffer, size);
  181.  
  182. pthread_mutex_unlock(&mutexes[fd]);
  183.  
  184. pthread_exit(NULL);
  185. }
  186.  
  187. pthread_t *writingThreads;
  188. pthread_mutex_t rmutex;
  189.  
  190. void *readThread(void *ign) {
  191. struct Read arg = *((struct Read *) ign);
  192. int fd = arg.fd;
  193. int cc = arg.cc;
  194. printf("fd = %d\n", fd);
  195. char *original = arg.original;
  196. printf("HEADER: %s\n", original);
  197. // MARK: --Reading the image
  198. int i = 0, j = 0, header;
  199. long size;
  200. char len[1024], newTag[1024];
  201. while (original[i] != ' ')
  202. i++;
  203. i++;
  204. if (original[i] == '#') {
  205. while (original[i] != ' ') {
  206. newTag[j] = original[i];
  207. i++;
  208. j++;
  209. }
  210. i++;
  211. }
  212. j = 0;
  213. while (original[i] != '/') {
  214. len[j] = original[i];
  215. i++;
  216. j++;
  217. }
  218. len[j] = '\0';
  219. size = atol(len);
  220. printf("Size is %ld\n", size);
  221. char *ibuffer = (char *) malloc (sizeof(char) * size);
  222. long count = 0;
  223. while (count < size) {
  224. char temp[1];
  225. int many = read(fd, temp, 1);
  226. // printf("Read %ld\n",count);
  227. if (many <= 0)
  228. printf("Dropped byte.\n");
  229. memcpy(ibuffer+many, temp, many);
  230. count += many;
  231. }
  232. printf("\nStarting to send...\n");
  233.  
  234. // MARK: --Writing the image
  235. int k;
  236. char send[cc];
  237. for(k = 0; k < cc; k++)
  238. send[k] = original[k];
  239. i = 0;
  240. if (newTag[0] == '#') {
  241. struct Client *user = users;
  242. while (user != NULL) {
  243. struct Tag *Tag = user->tag;
  244. while (Tag != NULL) {
  245. if (strcmp(Tag->tagName, newTag) == 0) {
  246. // threads
  247. struct Write toWrite;
  248. toWrite.fd = user->fd;
  249. toWrite.send = send;
  250. toWrite.cc = cc;
  251. toWrite.ibuffer = ibuffer;
  252. toWrite.size = size;
  253. int status = pthread_create(&writingThreads[user->fd], NULL, &writeThread, &toWrite);
  254. if (status != 0)
  255. printf( "pthread_create error %d.\n", status );
  256. }
  257. Tag = Tag->next;
  258. }
  259. user = user->next;
  260. }
  261. } else {
  262. struct Client *user = users;
  263. while (user != NULL) {
  264. if (user->all == true) {
  265. // threads
  266. struct Write toWrite;
  267. toWrite.fd = user->fd;
  268. toWrite.send = send;
  269. toWrite.cc = cc;
  270. toWrite.ibuffer = ibuffer;
  271. toWrite.size = size;
  272. int status = pthread_create(&writingThreads[user->fd], NULL, &writeThread, &toWrite);
  273. if (status != 0)
  274. printf( "pthread_create error %d.\n", status );
  275. }
  276. user = user->next;
  277. }
  278. }
  279.  
  280. // pthread_join
  281. for ( j = 0; j < nfds; j++ )
  282. if (FD_ISSET(j, &rfds))
  283. pthread_join( writingThreads[j], NULL );
  284. pthread_mutex_lock(&rmutex);
  285. FD_SET(fd, &afds);
  286. pthread_mutex_unlock(&rmutex);
  287. printf("Completed.\n");
  288. free(ibuffer);
  289. pthread_exit(NULL);
  290. }
  291.  
  292. int
  293. main( int argc, char *argv[] )
  294. {
  295. char buf[BUFSIZE];
  296. char *service;
  297. struct sockaddr_in fsin;
  298. int msock;
  299. int ssock;
  300. int alen;
  301. int fd;
  302. int rport = 0;
  303. int cc;
  304. int i;
  305.  
  306. switch (argc)
  307. {
  308. case 1:
  309. // No args? let the OS choose a port and tell the user
  310. rport = 1;
  311. break;
  312. case 2:
  313. // User provides a port? then use it
  314. service = argv[1];
  315. break;
  316. default:
  317. fprintf( stderr, "usage: server [port]\n" );
  318. exit(-1);
  319. }
  320.  
  321. msock = passivesock( service, "tcp", QLEN, &rport );
  322. if (rport)
  323. {
  324. // Tell the user the selected port
  325. printf( "server: port %d\n", rport );
  326. fflush( stdout );
  327. }
  328.  
  329. nfds = getdtablesize();
  330. pthread_t readingThreads[nfds];
  331. writingThreads = (pthread_t *) malloc (sizeof(pthread_t) * nfds);
  332. mutexes = (pthread_mutex_t *) malloc (sizeof(pthread_mutex_t) * nfds);
  333. for (i = 0; i < nfds; i++)
  334. pthread_mutex_init(&mutexes[i], NULL);
  335.  
  336. FD_ZERO(&afds);
  337. FD_SET( msock, &afds );
  338.  
  339. for (;;)
  340. {
  341. struct timeval time;
  342. time.tv_sec = 1;
  343.  
  344. memcpy((char *)&rfds, (char *)&afds, sizeof(rfds));
  345.  
  346. if (select(nfds, &rfds, (fd_set *)0, (fd_set *)0,
  347. &time) < 0)
  348. {
  349. fprintf( stderr, "server select: %s\n", strerror(errno) );
  350. exit(-1);
  351. }
  352.  
  353. /* Handle the main socket - a new guy has checked in */
  354. if (FD_ISSET( msock, &rfds))
  355. {
  356. int ssock;
  357.  
  358. alen = sizeof(fsin);
  359. ssock = accept( msock, (struct sockaddr *)&fsin, &alen );
  360. if (ssock < 0)
  361. {
  362. fprintf( stderr, "accept: %s\n", strerror(errno) );
  363. exit(-1);
  364. }
  365. /* start listening to this guy */
  366. FD_SET( ssock, &afds );
  367. printf("Guy is %d\n", ssock);
  368.  
  369. }
  370.  
  371. /* Handle the participants requests */
  372. for ( fd = 0; fd < nfds; fd++ )
  373. {
  374. if (fd != msock && FD_ISSET(fd, &rfds))
  375. {
  376. // add to users linked list
  377. struct Client* temp = (struct Client*) malloc (sizeof(struct Client*));
  378. bool userExists = false;
  379. int j;
  380. struct Client* temp1 = (struct Client*) malloc (sizeof(struct Client*));
  381. temp1 = users;
  382. for(j = 0; j < usersCount; j++) {
  383. if(temp1->fd == fd) {
  384. userExists = true;
  385. break;
  386. }
  387. temp1 = temp1->next;
  388. }
  389. if (!userExists) {
  390. temp->fd = fd;
  391. temp->all = false;
  392. temp->next = users;
  393. temp->tag = NULL;
  394. users = temp;
  395. usersCount++;
  396. }
  397. if ( (cc = read( fd, buf, BUFSIZE )) <= 0 )
  398. {
  399. printf( "The User%d has gone.\n", fd );
  400. (void) close(fd);
  401. FD_CLR( fd, &afds );
  402.  
  403. }
  404. else
  405. {
  406. buf[cc] = '\0';
  407. printf( "The User%d says: %s\n", fd, buf );
  408. char *original = (char *) malloc (sizeof(char) * strlen(buf));
  409. strcpy(original, buf);
  410. strcat(original, "\n");
  411.  
  412. char *response, *tag;
  413. char *cmd = strtok(buf, " ");
  414.  
  415. /* Understand what that message means */
  416. if (strcmp(cmd, "REGISTERALL\r\n") == 0) {
  417. registerUser(fd);
  418. }
  419. else if (strcmp(cmd, "DEREGISTERALL\r\n") == 0) {
  420. deregisterUser(fd);
  421. }
  422. else if (strcmp(cmd, "REGISTER") == 0) {
  423. tag = strtok(NULL, " \n\r\n");
  424. char *newTag = (char*) malloc (sizeof(char)*strlen(tag));
  425. strcpy(newTag, tag);
  426. insertTag(fd, newTag);
  427. printTags(fd);
  428. }
  429. else if (strcmp(cmd, "DEREGISTER") == 0) {
  430. tag = strtok(NULL, "\r\n");
  431. char *newTag = (char*) malloc (sizeof(char)*strlen(tag));
  432. strcpy(newTag, tag);
  433. deleteTag(fd, newTag);
  434. printTags(fd);
  435. }
  436. else if (strcmp(cmd, "MSG") == 0) {
  437. response = strtok(NULL, "\r\n");
  438. if (response[0] == '#') {
  439. tag = strtok(response, " ");
  440. char *newTag = (char*) malloc (sizeof(char)*strlen(tag));
  441. strcpy(newTag, tag);
  442. response = strtok(NULL, "\r\n");
  443. response = strcat(response, "\n");
  444. // find all registered users
  445. struct Client* temp = users;
  446. int i;
  447. for(i = 0; i < usersCount; i++) {
  448. struct Tag* Tag = temp->tag;
  449. while(Tag != NULL) {
  450. if(strcmp(Tag->tagName,newTag) == 0) {
  451. write(temp->fd, original, strlen(original));
  452. }
  453. Tag = Tag->next;
  454. }
  455. temp = temp->next;
  456. }
  457. }
  458. else {
  459. response = strcat(response, "\n");
  460. // find all registered users
  461. struct Client* temp = users;
  462. int i;
  463. for(i = 0; i < usersCount; i++) {
  464. if(temp->all == true) {
  465. write(temp->fd, original, strlen(original));
  466. }
  467. temp = temp->next;
  468. }
  469. }
  470. }
  471. else if (strcmp(cmd, "MSGE") == 0) {
  472. response = strtok(NULL, "\0");
  473. if (response[0] == '#') {
  474. tag = strtok(response, " ");
  475. char *newTag = (char*) malloc (sizeof(char)*strlen(tag));
  476. strcpy(newTag, tag);
  477. // find all registered users
  478. struct Client* temp = users;
  479. int i;
  480. for(i = 0; i < usersCount; i++) {
  481. struct Tag* Tag = temp->tag;
  482. while(Tag != NULL) {
  483. if(strcmp(Tag->tagName,newTag) == 0) {
  484. write(temp->fd, original, strlen(original));
  485. }
  486. Tag = Tag->next;
  487. }
  488. temp = temp->next;
  489. }
  490. }
  491. else {
  492. // find all registered users
  493. struct Client* temp = users;
  494. int i;
  495. for(i = 0; i < usersCount; i++) {
  496. if(temp->all == true) {
  497. write(temp->fd, original, strlen(original));
  498. }
  499. temp = temp->next;
  500. }
  501. }
  502. }
  503. else if (strcmp(cmd, "IMAGE") == 0) {
  504. // arg
  505. struct Read arg;
  506. arg.fd = fd;
  507. arg.original = original;
  508. arg.cc = cc;
  509. FD_CLR(fd, &afds);
  510. int st = pthread_create(&readingThreads[fd], NULL, &readThread, &arg);
  511. if (st != 0) {
  512. printf("Error creating a thread.\n");
  513. FD_SET(fd, &afds);
  514. }
  515. }
  516. else {
  517. response = "Oops! Sorry, I can't understand you.\n";
  518. write(fd, response, strlen(response));
  519. }
  520. }
  521. }
  522. }
  523. }
  524. pthread_exit(0);
  525. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement