Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _BSD_SOURCE
- #define NUM_ARGS 2
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <sys/stat.h>
- #include <sys/socket.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <string.h>
- #include <pthread.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <errno.h>
- #define SERVER_PORT 4061
- #define MAX_CONNECTIONS 100
- struct bankAccount {
- float balance;
- pthread_mutex_t* mutex;
- };
- struct threadArg {
- struct bankAccount* acct;
- double change;
- int clientfd;
- };
- int makeargv(const char *s, const char *delimiters, char ***argvp) {
- int error;
- int i;
- int numtokens;
- const char *snew;
- char *t;
- char *saveptr;
- if ((s == NULL) || (delimiters == NULL) || (argvp == NULL)) {
- errno = EINVAL;
- return -1;
- }
- *argvp = NULL;
- snew = s + strspn(s, delimiters);
- if ((t = malloc(strlen(snew) + 1)) == NULL)
- return -1;
- strcpy(t,snew);
- numtokens = 0;
- if (strtok_r(t, delimiters,&saveptr) != NULL)
- for (numtokens = 1; strtok_r(NULL, delimiters,&saveptr) != NULL; numtokens++) ;
- if ((*argvp = malloc((numtokens + 1)*sizeof(char *))) == NULL) {
- error = errno;
- free(t);
- errno = error;
- return -1;
- }
- if (numtokens == 0)
- free(t);
- else {
- strcpy(t,snew);
- **argvp = strtok_r(t,delimiters,&saveptr);
- for (i=1; i<numtokens; i++)
- *((*argvp) +i) = strtok_r(NULL,delimiters,&saveptr);
- }
- *((*argvp) + numtokens) = NULL;
- return numtokens;
- }
- void threadFunction(void* args) {
- struct threadArg* arg = args;
- struct bankAccount* acct = arg->acct;
- // Alter the specified account;
- pthread_mutex_lock(acct->mutex);
- printf("current balance: %f\n", acct->balance);
- acct->balance += arg->change;
- pthread_mutex_unlock(acct->mutex);
- // Write back to client.
- char* resp = malloc(sizeof(char)*256);
- sprintf(resp, "%f\0", acct->balance);
- write(arg->clientfd, resp, strlen(resp));
- // Close client connection.
- close(arg->clientfd);
- free(args);
- }
- int main(int argc, char** argv) {
- if (argc > NUM_ARGS + 1) {
- printf("Wrong number of args, expected %d, given %d\n", NUM_ARGS, argc - 1);
- exit(1);
- }
- // Create a TCP socket.
- int sock = socket(AF_INET , SOCK_STREAM , 0);
- // Bind it to a local address.
- struct sockaddr_in servAddress;
- servAddress.sin_family = AF_INET;
- servAddress.sin_port = htons(SERVER_PORT);
- servAddress.sin_addr.s_addr = htonl(INADDR_ANY);
- bind(sock, (struct sockaddr *) &servAddress, sizeof(servAddress));
- // We must now listen on this port.
- listen(sock, atoi(argv[2]));
- struct bankAccount** accounts = malloc(sizeof(struct bankAccount*)*atoi(argv[1]));
- for (int i = 0; i < atoi(argv[1]); i++) {
- accounts[i] = malloc(sizeof(struct bankAccount));
- accounts[i]->balance = 2500;
- accounts[i]->mutex = malloc(sizeof(pthread_mutex_t));
- pthread_mutex_init(accounts[i]->mutex, NULL);
- }
- struct threadArg** args = malloc(sizeof(struct threadArg*)*atoi(argv[1]));
- for (int i = 0; i < atoi(argv[1]); i++) {
- args[i] = malloc(sizeof(struct threadArg));
- }
- // A server typically runs infinitely, with some boolean flag to terminate.
- while (1) {
- // Now accept the incoming connections.
- struct sockaddr_in clientAddress;
- socklen_t size = sizeof(struct sockaddr_in);
- int clientfd = accept(sock, (struct sockaddr*) &clientAddress, &size);
- // Read request from the socket.
- char* req = malloc(sizeof(char)*256);
- ssize_t reqSize = recv(clientfd, req, 256, 0);
- char** splitReq = malloc(sizeof(char)*reqSize);
- makeargv(req, ";", &splitReq);
- struct threadArg* arg = args[atoi(splitReq[0])];
- printf("acct: %i, change: %f\n", atoi(splitReq[0]), atof(splitReq[1]));
- arg->acct = accounts[atoi(splitReq[0])];
- arg->change = atof(splitReq[1]);
- arg->clientfd = clientfd;
- pthread_mutex_t t;
- pthread_create(&t, NULL, threadFunction, (void*)arg);
- pthread_detach(&t);
- free(req);
- free(splitReq);
- }
- // Close the socket.
- close(sock);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement