Devember: Distributed calculator

This post is part of the Devember collection, useful for the study of the Socket API.

Devember: Distributed calculator

It’s been a week since I started my devlogs for Devember and finally today I’ve done something more complex than previous exercises: a distributed calculator.

The communication takes place via UDP, so I’ve used the sendto and recvfrom functions. Managing the client input has been a bit cumbersome but eventually I did:

char buff[MAXLINE];
int a = 0;
int b = 0;
char op[OP_LEN] = "+";
while (fgets(buff, MAXLINE, stdin) != NULL) {
	if (sscanf(buff, "%d %s %d", &a, op, &b) == 3) {
		// ... do networking
	}
}

On the other end, the server receives the datagram, interprets the data, computes the results and sends it back to the client:

char buff[MAXLINE];
socklen_t len;

int a;
int b;
char op[OP_LEN];

while (1) {
	// Receive datagram
	len = clilen;
	if (recvfrom(sockfd, buff, MAXLINE, 0, cliaddr, &len) < 0) {
		perror("recvfrom");
		return -1;
	}

	// Interpret data and compute the result
	if (sscanf(buff, "%d %s %d", &a, op, &b) == 3) {
		if (strcmp(op, "+") == 0) {
			sprintf(buff, "%d", a + b);
		} else if (strcmp(op, "-") == 0) {
			sprintf(buff, "%d", a - b);
		} else if (strcmp(op, "*") == 0) {
			sprintf(buff, "%d", a * b);
		} else if (strcmp(op, "/") == 0) {
			if (b != 0) {
				sprintf(buff, "%d", a / b);
			} else {
				sprintf(buff, "Undefined");
			}
		} else if (strcmp(op, "mod") == 0) {
			sprintf(buff, "%d", a % b);
		} else {
			sprintf(buff, "Invalid operator");
		}
	} else {
		sprintf(buff, "Invalid message");
	}

	// Send result to the client
	if (sendto(sockfd, buff, strlen(buff), 0, cliaddr, len) < 0) {
		perror("sendto");
		return -1;
	}
}

The complete code can be found on this repository.

8 December 2015