Advertisement
Guest User

Untitled

a guest
Apr 25th, 2018
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.00 KB | None | 0 0
  1. #define _BSD_SOURCE
  2. #define NUM_ARGS 2
  3.  
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <sys/types.h>
  7. #include <sys/wait.h>
  8. #include <sys/stat.h>
  9. #include <sys/socket.h>
  10. #include <unistd.h>
  11. #include <fcntl.h>
  12. #include <string.h>
  13. #include <pthread.h>
  14. #include <netinet/in.h>
  15. #include <arpa/inet.h>
  16. #include <errno.h>
  17.  
  18. #define SERVER_PORT 4061
  19. #define MAX_CONNECTIONS 100
  20.  
  21. struct bankAccount {
  22. float balance;
  23. pthread_mutex_t* mutex;
  24. };
  25.  
  26. struct threadArg {
  27. struct bankAccount* acct;
  28. double change;
  29. int clientfd;
  30. };
  31.  
  32. int makeargv(const char *s, const char *delimiters, char ***argvp) {
  33. int error;
  34. int i;
  35. int numtokens;
  36. const char *snew;
  37. char *t;
  38. char *saveptr;
  39.  
  40. if ((s == NULL) || (delimiters == NULL) || (argvp == NULL)) {
  41. errno = EINVAL;
  42. return -1;
  43. }
  44. *argvp = NULL;
  45. snew = s + strspn(s, delimiters);
  46. if ((t = malloc(strlen(snew) + 1)) == NULL)
  47. return -1;
  48. strcpy(t,snew);
  49. numtokens = 0;
  50. if (strtok_r(t, delimiters,&saveptr) != NULL)
  51. for (numtokens = 1; strtok_r(NULL, delimiters,&saveptr) != NULL; numtokens++) ;
  52.  
  53. if ((*argvp = malloc((numtokens + 1)*sizeof(char *))) == NULL) {
  54. error = errno;
  55. free(t);
  56. errno = error;
  57. return -1;
  58. }
  59.  
  60. if (numtokens == 0)
  61. free(t);
  62. else {
  63. strcpy(t,snew);
  64. **argvp = strtok_r(t,delimiters,&saveptr);
  65. for (i=1; i<numtokens; i++)
  66. *((*argvp) +i) = strtok_r(NULL,delimiters,&saveptr);
  67. }
  68. *((*argvp) + numtokens) = NULL;
  69. return numtokens;
  70. }
  71.  
  72. void threadFunction(void* args) {
  73.  
  74. struct threadArg* arg = args;
  75. struct bankAccount* acct = arg->acct;
  76.  
  77. // Alter the specified account;
  78. pthread_mutex_lock(acct->mutex);
  79. printf("current balance: %f\n", acct->balance);
  80. acct->balance += arg->change;
  81. pthread_mutex_unlock(acct->mutex);
  82.  
  83.  
  84. // Write back to client.
  85. char* resp = malloc(sizeof(char)*256);
  86. sprintf(resp, "%f\0", acct->balance);
  87. write(arg->clientfd, resp, strlen(resp));
  88.  
  89. // Close client connection.
  90. close(arg->clientfd);
  91.  
  92. free(args);
  93. }
  94.  
  95. int main(int argc, char** argv) {
  96.  
  97. if (argc > NUM_ARGS + 1) {
  98.  
  99. printf("Wrong number of args, expected %d, given %d\n", NUM_ARGS, argc - 1);
  100. exit(1);
  101. }
  102.  
  103. // Create a TCP socket.
  104. int sock = socket(AF_INET , SOCK_STREAM , 0);
  105.  
  106. // Bind it to a local address.
  107. struct sockaddr_in servAddress;
  108. servAddress.sin_family = AF_INET;
  109. servAddress.sin_port = htons(SERVER_PORT);
  110. servAddress.sin_addr.s_addr = htonl(INADDR_ANY);
  111. bind(sock, (struct sockaddr *) &servAddress, sizeof(servAddress));
  112.  
  113. // We must now listen on this port.
  114. listen(sock, atoi(argv[2]));
  115.  
  116. struct bankAccount** accounts = malloc(sizeof(struct bankAccount*)*atoi(argv[1]));
  117.  
  118. for (int i = 0; i < atoi(argv[1]); i++) {
  119. accounts[i] = malloc(sizeof(struct bankAccount));
  120. accounts[i]->balance = 2500;
  121. accounts[i]->mutex = malloc(sizeof(pthread_mutex_t));
  122.  
  123. pthread_mutex_init(accounts[i]->mutex, NULL);
  124. }
  125.  
  126. struct threadArg** args = malloc(sizeof(struct threadArg*)*atoi(argv[1]));
  127.  
  128. for (int i = 0; i < atoi(argv[1]); i++) {
  129. args[i] = malloc(sizeof(struct threadArg));
  130. }
  131.  
  132.  
  133. // A server typically runs infinitely, with some boolean flag to terminate.
  134. while (1) {
  135.  
  136. // Now accept the incoming connections.
  137. struct sockaddr_in clientAddress;
  138.  
  139. socklen_t size = sizeof(struct sockaddr_in);
  140. int clientfd = accept(sock, (struct sockaddr*) &clientAddress, &size);
  141.  
  142. // Read request from the socket.
  143. char* req = malloc(sizeof(char)*256);
  144. ssize_t reqSize = recv(clientfd, req, 256, 0);
  145.  
  146. char** splitReq = malloc(sizeof(char)*reqSize);
  147. makeargv(req, ";", &splitReq);
  148.  
  149. struct threadArg* arg = args[atoi(splitReq[0])];
  150.  
  151. printf("acct: %i, change: %f\n", atoi(splitReq[0]), atof(splitReq[1]));
  152.  
  153. arg->acct = accounts[atoi(splitReq[0])];
  154. arg->change = atof(splitReq[1]);
  155. arg->clientfd = clientfd;
  156.  
  157. pthread_mutex_t t;
  158. pthread_create(&t, NULL, threadFunction, (void*)arg);
  159. pthread_detach(&t);
  160.  
  161. free(req);
  162. free(splitReq);
  163. }
  164.  
  165. // Close the socket.
  166. close(sock);
  167. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement