Question: A concurrent-thread Server is up and waiting for any client to connect and send a SQL request. When a client connected to the server, the

A concurrent-thread Server is up and waiting for any client to connect and send a SQL request. When a client connected to the server, the server will create a slave-thread to serve the connected client and thus to free the server to wait for any other incoming client. The slave-thread is then to receive a SQL statement from the client and call the sqlite3 database in the background to process the SQL transaction. The outcome of the SQL transaction is then to be sent back to the client.

The sqlite3 database is initially created as we worked in Week05 Activity. Initially the database is empty.

Design and implement the server (a4Server.c) and the client (a4Client.c) . The server is up and listening. The client connects to the server to do three transactions (to request what test1.c, test2.c and test3.c program do). First the client sends a SQL statement to be processed by the server (e.g., "select * from company;"). Then the server's thread is created and it receives the SQL statement sent (e.g., "select * from company;") which is to be processed by the background database, and it sends the result of the database back to the client.

[Note. You may like to design and implement this task above first and then to do the following items.]

In addition, the client then received the result of each request, to be displayed in the console. In addition, the client outputs its console's output to be saved in a log file (a4ClientLog.txt). The log file of the client is opened in the beginning, writing each result with a proper heading, and then to be closed at the end of the client program.

The client displays a message (with a time of day with its PID) to the console saying that it is going to do. The client displays each transaction to be sent (with a time of day) and the result from the server (with a time of day). The first transaction is to create the company table. The second transaction is to insert the records into the company table. The third transaction is to select all the records from the company table. At the end, the client displays a message (with a time of day) to the console saying that it is now to be terminated.

In addition, the server opens its log file (a4ServerLog.txt) to be shared by its threads. Then each server's thread displays a message (with a time of day with PID and its thread ID) to the console saying that it is going to process a client's request (SQL statement). Also each thread places a log message to the log file. For each transaction received, it will display it to the console with a proper heading (with a time of day), and the result of the transaction from the database (with a time of day). At the end of it, the server's thread displays a message (with a time of day with PID and its thread ID) to the console saying that is going to be terminated.

// conServerThread.c

#include

#include

#include

#include

#include

/*

CONCURRENT SERVER: THREAD EXAMPLE

Must be linked with the "pthread" library also, e.g.:

cc -o example example.c -lnsl -lsocket -lpthread

This program creates a connection socket, binds a name to it, then

listens for connections to the sockect. When a connection is made,

it accepts messages from the socket until eof, and then waits for

another connection...

This is an example of a CONCURRENT server -- by creating threads several

clients can be served at the same time...

This program has to be killed to terminate, or alternately it will abort in

120 seconds on an alarm...

*/

#define PORTNUMBER 10010

struct serverParm {

int connectionDesc;

};

void *serverThread(void *parmPtr) {

#define PARMPTR ((struct serverParm *) parmPtr)

int recievedMsgLen;

char messageBuf[1025];

/* Server thread code to deal with message processing */

printf("DEBUG: connection made, connectionDesc=%d ",

PARMPTR->connectionDesc);

if (PARMPTR->connectionDesc < 0) {

printf("Accept failed ");

return(0); /* Exit thread */

}

/* Receive messages from sender... */

while ((recievedMsgLen=

read(PARMPTR->connectionDesc,messageBuf,sizeof(messageBuf)-1)) > 0)

{

recievedMsgLen[messageBuf] = '\0';

printf("Message: %s ",messageBuf);

if (write(PARMPTR->connectionDesc,"GOT IT\0",7) < 0) {

perror("Server: write error");

return(0);

}

}

close(PARMPTR->connectionDesc); /* Avoid descriptor leaks */

free(PARMPTR); /* And memory leaks */

return(0); /* Exit thread */

}

main () {

int listenDesc;

struct sockaddr_in myAddr;

struct serverParm *parmPtr;

int connectionDesc;

pthread_t threadID;

/* For testing purposes, make sure process will terminate eventually */

alarm(120); /* Terminate in 120 seconds */

/* Create socket from which to read */

if ((listenDesc = socket(AF_INET, SOCK_STREAM, 0)) < 0) {

perror("open error on socket");

exit(1);

}

/* Create "name" of socket */

myAddr.sin_family = AF_INET;

myAddr.sin_addr.s_addr = INADDR_ANY;

myAddr.sin_port = htons(PORTNUMBER);

if (bind(listenDesc, (struct sockaddr *) &myAddr, sizeof(myAddr)) < 0) {

perror("bind error");

exit(1);

}

/* Start accepting connections.... */

/* Up to 5 requests for connections can be queued... */

listen(listenDesc,5);

while (1) /* Do forever */ {

/* Wait for a client connection */

connectionDesc = accept(listenDesc, NULL, NULL);

/* Create a thread to actually handle this client */

parmPtr = (struct serverParm *)malloc(sizeof(struct serverParm));

parmPtr->connectionDesc = connectionDesc;

if (pthread_create(&threadID, NULL, serverThread, (void *)parmPtr)

!= 0) {

perror("Thread create error");

close(connectionDesc);

close(listenDesc);

exit(1);

}

printf("Parent ready for another connection ");

}

}

TEST0.c

// g++ text.c -l sqlite3

#include #include

int main(int argc, char* argv[]) { sqlite3 *db; char *zErrMsg = 0; int rc;

rc = sqlite3_open("test.db", &db);

if( rc ){ fprintf(stderr, "Can't open database: %s ", sqlite3_errmsg(db)); }else{ fprintf(stderr, "Opened database successfully "); } sqlite3_close(db); }

TEST1.c

#include #include #include

static int callback(void *NotUsed, int argc, char **argv, char **azColName){ int i; for(i=0; i

int main(int argc, char* argv[]) { sqlite3 *db; char *zErrMsg = 0; int rc; char *sql;

/* Open database */ rc = sqlite3_open("test.db", &db); if( rc ){ fprintf(stderr, "Can't open database: %s ", sqlite3_errmsg(db)); exit(0); }else{ fprintf(stdout, "Opened database successfully "); }

/* Create SQL statement */ sql = "CREATE TABLE COMPANY(" \ "ID INT PRIMARY KEY NOT NULL," \ "NAME TEXT NOT NULL," \ "AGE INT NOT NULL," \ "ADDRESS CHAR(50)," \ "SALARY REAL );";

/* Execute SQL statement */ rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); if( rc != SQLITE_OK ){ fprintf(stderr, "SQL error: %s ", zErrMsg); sqlite3_free(zErrMsg); }else{ fprintf(stdout, "Table created successfully "); } sqlite3_close(db); return 0; }

TEST2.c

#include #include #include

static int callback(void *NotUsed, int argc, char **argv, char **azColName){ int i; for(i=0; i

int main(int argc, char* argv[]) { sqlite3 *db; char *zErrMsg = 0; int rc; char *sql;

/* Open database */ rc = sqlite3_open("test.db", &db); if( rc ){ fprintf(stderr, "Can't open database: %s ", sqlite3_errmsg(db)); exit(0); }else{ fprintf(stderr, "Opened database successfully "); }

/* Create SQL statement */ sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " \ "VALUES (1, 'Paul', 32, 'California', 20000.00 ); " \ "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " \ "VALUES (2, 'Allen', 25, 'Texas', 15000.00 ); " \ "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \ "VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );" \ "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \ "VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );";

/* Execute SQL statement */ rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); if( rc != SQLITE_OK ){ fprintf(stderr, "SQL error: %s ", zErrMsg); sqlite3_free(zErrMsg); }else{ fprintf(stdout, "Records created successfully "); } sqlite3_close(db); return 0; }

TEST3.c

#include #include #include

static int callback(void *data, int argc, char **argv, char **azColName){ int i; fprintf(stderr, "%s: ", (const char*)data); for(i=0; i

int main(int argc, char* argv[]) { sqlite3 *db; char *zErrMsg = 0; int rc; char *sql; const char* data = "Callback function called";

/* Open database */ rc = sqlite3_open("test.db", &db); if( rc ){ fprintf(stderr, "Can't open database: %s ", sqlite3_errmsg(db)); exit(0); }else{ fprintf(stderr, "Opened database successfully "); }

/* Create SQL statement */ sql = "SELECT * from COMPANY";

/* Execute SQL statement */ rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg); if( rc != SQLITE_OK ){ fprintf(stderr, "SQL error: %s ", zErrMsg); sqlite3_free(zErrMsg); }else{ fprintf(stdout, "Operation done successfully "); } sqlite3_close(db); return 0; }

TEST4.c

#include #include #include

static int callback(void *data, int argc, char **argv, char **azColName){ int i; fprintf(stderr, "%s: ", (const char*)data); for(i=0; i

int main(int argc, char* argv[]) { sqlite3 *db; char *zErrMsg = 0; int rc; char *sql; const char* data = "Callback function called";

/* Open database */ rc = sqlite3_open("test.db", &db); if( rc ){ fprintf(stderr, "Can't open database: %s ", sqlite3_errmsg(db)); exit(0); }else{ fprintf(stderr, "Opened database successfully "); }

/* Create merged SQL statement */ sql = "UPDATE COMPANY set SALARY = 25000.00 where ID=1; " \ "SELECT * from COMPANY";

/* Execute SQL statement */ rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg); if( rc != SQLITE_OK ){ fprintf(stderr, "SQL error: %s ", zErrMsg); sqlite3_free(zErrMsg); }else{ fprintf(stdout, "Operation done successfully "); } sqlite3_close(db); return 0; }

TEST5.c

#include #include #include

static int callback(void *data, int argc, char **argv, char **azColName){ int i; fprintf(stderr, "%s: ", (const char*)data); for(i=0; i

int main(int argc, char* argv[]) { sqlite3 *db; char *zErrMsg = 0; int rc; char *sql; const char* data = "Callback function called";

/* Open database */ rc = sqlite3_open("test.db", &db); if( rc ){ fprintf(stderr, "Can't open database: %s ", sqlite3_errmsg(db)); exit(0); }else{ fprintf(stderr, "Opened database successfully "); }

/* Create merged SQL statement */ sql = "DELETE from COMPANY where ID=2; " \ "SELECT * from COMPANY";

/* Execute SQL statement */ rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg); if( rc != SQLITE_OK ){ fprintf(stderr, "SQL error: %s ", zErrMsg); sqlite3_free(zErrMsg); }else{ fprintf(stdout, "Operation done successfully "); } sqlite3_close(db); return 0; }

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Databases Questions!