Edward Lin
edward.lin/*
* bmpServer.c
* 1917 serve that 3x3 bmp from lab3 Image activity
*
* Created by Tim Lambert on 02/04/12.
* Containing code created by Richard Buckland on 28/01/11.
* Copyright 2012 Licensed under Creative Commons SA-BY-NC 3.0.
*
*/
#include "pixelColor.h"
#include "mandelBrot.h"
// after serving this many pages the server will halt
int main(int argc, char *argv[]) {
printf("************************************\n");
printf("Starting simple server %f\n", SIMPLE_SERVER_VERSION);
printf("Serving bmps since 2012\n");
int serverSocket = makeServerSocket (DEFAULT_PORT);
printf("Access this server at http://localhost:%d/\n", DEFAULT_PORT);
printf("************************************\n");
char request[REQUEST_BUFFER_SIZE] = {0};
int numberServed = 0;
while (numberServed < NUMBER_OF_PAGES_TO_SERVE) {
printf("*** So far served %d pages ***\n", numberServed);
int connectionSocket = waitForConnection(serverSocket);
// wait for a request to be sent from a web browser, open a new
// connection for this conversation
// read the first line of the request sent by the browser
int bytesRead;
bytesRead = read(connectionSocket, request, (sizeof request)-1);
assert(bytesRead >= 0);
// were we able to read any data from the connection?
double x1;
double y1;
double zoom1;
char header[REQUEST_BUFFER_SIZE];
int position = 0;
while (request[position] != 'b'){
header[position] = request[position+5];
position++;
}
// print entire request to the console
printf (" *** Received http request ***\n %s\n", request);
if (request[5] == ' ') { //if string size = 0
serveHTML(connectionSocket);
x1 = 0;
y1 = 0;
zoom1 = 0;
} else {
int counter1 = 1;
char part_x[strlen(header)];
while (header[counter1] != '_') {
part_x[counter1-1] = header[counter1];
counter1++;
}
part_x[counter1-1] = '\0'; //end string
counter1 = counter1 +2; // jump two to start of Y
int counter2 = 0;
char part_y[strlen(header)];
while(header[counter1] != '_') {
part_y[counter2] = header[counter1];
counter1++;
counter2++;
}
part_y[counter2] = '\0'; //end string
counter1 = counter1+2; //jump two to start of Z
char part_z[strlen(header)];
int count3 =0;
while (header[counter1] != '.') {
part_z[count3] = header[counter1];
count3++;
counter1++;
}
part_z[count3] = '\0'; //end of string
char * pointer_x = (part_x);
char * pointer_y = (part_y);
char * pointer_z = (part_z);
x1 = run_strtod(pointer_x);
y1 = run_strtod(pointer_y);
zoom1 = run_strtod(pointer_z);
//send the browser a simple html page using http
printf (" *** Sending http response ***\n");
serveBMP(connectionSocket, x1, y1, zoom1);
}
// close the connection after sending the page- keep aust beautiful
close(connectionSocket);
numberServed++;
}
// close the server connection after we are done- keep aust beautiful
printf("** shutting down the server **\n");
close(serverSocket);
return EXIT_SUCCESS;
}
void serveBMP(int socket, double x1, double y1, double zoom1) {
char* message;
// (if you write stings one after another like this on separate
// lines the c compiler kindly joins them togther for you into
// one long string)
message = "HTTP/1.0 200 OK\r\n"
"Content-Type: image/bmp\r\n"
"\r\n";
// first send the http response header
printf ("about to send=> %s\n", message);
write (socket, message, strlen (message));
// now send the BMP
unsigned char bmp[BMP_FILE_SIZE] = {0};
createBMP(bmp, x1, y1, zoom1);
write (socket, bmp, sizeof(bmp));
}
// -------------------------------------------------------
// start the server listening on the specified port number
// -------------------------------------------------------
int makeServerSocket(int portNumber) {
// create socket
int serverSocket = socket(AF_INET, SOCK_STREAM, 0);
assert(serverSocket >= 0);
// error opening socket
// bind socket to listening port
struct sockaddr_in serverAddress;
bzero((char *) &serverAddress, sizeof(serverAddress));
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = INADDR_ANY;
serverAddress.sin_port = htons(portNumber);
// let the server start immediately after a previous shutdown
int optionValue = 1;
setsockopt(
serverSocket,
SOL_SOCKET,
SO_REUSEADDR,
&optionValue,
sizeof(int)
);
int bindSuccess =
bind(
serverSocket,
(struct sockaddr *) &serverAddress,
sizeof (serverAddress)
);
assert(bindSuccess >= 0);
// if this assert fails wait a short while to let the operating
// system clear the port before trying again
return serverSocket;
}
// ------------------------------------------------------------
// wait for a browser to request a connection,
// returns the socket on which the conversation will take place
// ------------------------------------------------------------
int waitForConnection(int serverSocket) {
// listen for a connection
const int serverMaxBacklog = 10;
listen(serverSocket, serverMaxBacklog);
// accept the connection
struct sockaddr_in clientAddress;
socklen_t clientLen = sizeof (clientAddress);
int connectionSocket =
accept(
serverSocket,
(struct sockaddr *) &clientAddress,
&clientLen
);
assert(connectionSocket >= 0);
// error on accept
return (connectionSocket);
}
int createBMP(unsigned char bmp[BMP_FILE_SIZE], double x1, double y1, double zoom1) {
double y = y1;
double x = x1;
double zoom = zoom1;
zoom = configureZoom(zoom);
unsigned char header[] =
{0x42,0x4d,0x5a,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x36,0x00,0x00,0x00,0x28,0x00,
0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,
0x00,0x00,
0x01,0x00,0x18,0x00,0x00,0x00,0x00,0x00,
0x24,0x00,0x00,0x00,0x13,0x0b,0x00,0x00,
0x13,0x0b,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,};
unsigned char body[BMP_BODY_SIZE] = {0};
int pixel_array = 0;
double yposition = 0;
while (yposition< bmpSize) {
double xposition = 0;
while (xposition < bmpSize) {
int iterations = setCheck(yposition, xposition, x, y, zoom);
if (setCheck(yposition, xposition, x, y, zoom) > minIterations &&
setCheck(yposition, xposition, x, y, zoom) < maxIterations) {
body[pixel_array] = stepsToBlue(iterations);
body[pixel_array+1] = stepsToGreen(iterations);
body[pixel_array+2] = stepsToRed(iterations);
pixel_array = pixel_array+3;
} else {
body[pixel_array] = 0x00;
body[pixel_array+1] = 0x00;
body[pixel_array+2] = 0x00;
pixel_array = pixel_array+3;
}
xposition++;
}
yposition++;
}
int count1 = 0;
while (count1 <BMP_HEADER_SIZE) {
bmp[count1] = header[count1];
count1++;
}
int count2 = 0;
while (count2 < BMP_BODY_SIZE) {
bmp[count2+BMP_HEADER_SIZE] = body[count2]; //these two loops just put
count2++; //the header and the body together
}
return EXIT_SUCCESS;
}
int setCheck(double yposition, double xposition, double x, double y, double zoom) {
double point_x = (xposition - maxIterations)/(zoom) +x; // the -2 just orientates it , and adding
// x makes the new co ordinate the origin
double point_y = (yposition - maxIterations)/(zoom) +y;
int count = 0;
double Re = 0;
double Im = 0;
double tempx = 0;
while ((count < maxIterations) && ((Re*Re + Im*Im) <= 4)) {
tempx = Re;
Re = (Re)*(Re) - (Im)*(Im) + point_x;
Im = (2*tempx*Im) + point_y;
count++;
}
return count;
}
double configureZoom(double zoom) {
double number = 2;
int counter = 0;
while (counter != zoom) {
number = 2*number;
counter++;
}
number = number/2;
return number;
}
void serveHTML(int socket) {
char* message;
// first send the http response header
message =
"HTTP/1.0 200 Found\n"
"Content-Type: text/html\n"
"\n";
printf("about to send=> %s\n", message);
write(socket, message, strlen(message));
message =
"<!DOCTYPE html>\n"
"<html>\n"
"<script src=\"https://almondbread.openlearning.com/tileviewer.js\"></script>\n"
"</html>\n";
write(socket, message, strlen(message));
}
double run_strtod(char * input) {
double output;
char * end;
output = strtod(input, & end);
return output;
}
Download file:
mandelBrot.c
(9.1 KB)