Tcp server client Connection issue in C - c

so i am trying to implement a TCP server-client(s) using server ip and port. Connection between the two was established, with the use of threads.
Now i'm expecting the program to: for everytime a client joins or leave, if there are other clients present, then it will print "Client has joined/left the server" on these other clients screen. However if it is the only client present, it won't say the join or leave stuff and will proceed with asking user an input of what does the client wants to do.(user input is what the client has typed after this arrow ">")
What it is actually doing: When the first client has successfully joined the server, the command line remains empty, the ">" does not appear and even if you can type, no input is recorded by the client. As you connect a second client, that's when the arrow appears on the first client only and you can start inputting.
I would like to know which part i should edit to make my client when alone to start taking input without needing another client to join before doing so + When there are multiple clients and a client joins/leave, on the other clients' screen is printed "Client has joined/left the server"
Server code
void client_queuing(client_thr *cl){
pthread_mutex_lock(&cli_mutex);
for(int i=0; i < MAXLINE; ++i){
if(!cli[i]){
cli[i] = cl;
break;
}
}
pthread_mutex_unlock(&cli_mutex);
}
void client_removal(int uid){
pthread_mutex_lock(&cli_mutex);
for(int i=0; i < MAXLINE; ++i){
if(cli[i]){
if(cli[i]->uid == uid){
cli[i] = NULL;
break;
}
}
}
pthread_mutex_unlock(&cli_mutex);
}
void convey_msg(char *st, int uid){
pthread_mutex_lock(&cli_mutex);
for(int i=0; i<MAXLINE; ++i){
if(cli[i]){
if(cli[i]->uid != uid){
if(write(cli[i]->sockfd, st, strlen(st)) < 0){
perror("ERROR: Failure to write to descriptor");
break;
}
}
}
}
pthread_mutex_unlock(&cli_mutex);
}
void *man_cli(void *arg){
char buffer_o[SIZEOF_BUFFER];
char nickname[20];
int leave_flag = 0;
num_client++;
client_thr *clice = (client_thr *)arg;
// nickname
if(recv(clice->sockfd, nickname, 20, 0) <= 0 || strlen(nickname) >= 19){
printf("Name not Entered.\n");
leave_flag = 1;
}
else{
strcpy(cli->nickname, nickname);
sprintf(buffer_o, "A new user %s has joined SNC!\n", cli->nickname);
printf("%s", buffer_o);
convey_msg(buffer_o, clice->uid);
}
bzero(buffer_o, SIZEOF_BUFFER);
while(1){
if (leave_flag) {
break;
}
int receive = recv(clice->sockfd, buffer_o, SIZEOF_BUFFER, 0);
if (receive > 0){
if(strlen(buffer_o) > 0){
convey_msg(buffer_o, clice->uid);
array_trimming(buffer_o, strlen(buffer_o));
printf("%s -> %s\n", buffer_o, clice->nickname);
//printf("%s\n", buffer_o);
}
}
else if (receive == 0 || strcmp(buffer_o, "quit") == 0){
sprintf(buffer_o, "Server: %s has stopped chatting.\n", clice->nickname);
printf("%s", buffer_o);
convey_msg(buffer_o, clice->uid);
//trial
//strcpy(buffer_o, clice->nickname);
send(clice->sockfd, buffer_o, strlen(buffer_o)+1,0);
leave_flag = 1;
}
/* else {
printf("Error is -1\n");
leave_flag = 1;
} */
bzero(buffer_o, SIZEOF_BUFFER);
}
/* Delete client from queue and yield thread */
close(clice->sockfd);
client_removal(clice->uid);
free(clice);
num_client--;
pthread_detach(pthread_self());
return NULL;
}
client code
void handle_message_convey() {
char message[LENGTH] = {};
char buff[LENGTH + 20] = {};
while(1) {
flush_stdout();
fgets(message, LENGTH, stdin);
array_trimming(message, LENGTH);
if (strcmp(message, "quit") == 0) {
break;
}
else {
sprintf(buff, "%s: %s\n", nickname, message);
send(sockfd, buffer, strlen(buff), 0);
}
bzero(message, LENGTH);
bzero(buffer, LENGTH + 20);
}
quit_with_catch_ctrl_c(2);
}
void handle_message_recv() {
char message[LENGTH] = {};
while (1) {
int message_rcv = recv(sockfd, message, LEN, 0);
if (message_rcv > 0) {
printf("%s", message);
flush_stdout();
}
else if (message_rcv == 0) {
break;
}
else {
// nothing happens = -1
}
memset(message, 0, sizeof(message));
}
}
int main(){
recv(sock_fd, buffer_o, sizeof(buffer_o), 0);
//printf("%s \n", buffer_o);
pthread_t message_sending_thr;
if(pthread_create(&message_sending_thr, NULL, (void* ) handle_message_convey, NULL) != 0) {
printf("Error with pthread:");
}
//printf("Hello, Welcome!");
pthread_t message_del_thr;
if(pthread_create(&message_del_thr, NULL, (void *)handle_message_recv, NULL) != 0){
printf("Error with pthread");
}
}

Related

How to make server read only line by line

I'm trying to create a chatroom. I have a server that takes commands and does things with them and I have client that sends them. Im using poll to monitor multiple clients. Whenever my client sends a command with the arguments it reads that line and gets some characters from the following line in client.
client(relevant code):
char *data = "REGISTER Johndoe pass1ds3";
send(sockfd,data, strlen(data), 0);
char *data3= "LOGIN Johndoe pass1ds3";
send(sockfd,data3, strlen(data3), 0);
//The server would get "REGISTER Johndoe pass1ds3LOGIN" instead of "REGISTER Johndoe pass1ds3".
server(relevant par):
for (int i = 1; i < (numfds + 1); i++){
if(pollfds[i].revents & POLLRDNORM){
if (readCmd(&pollfds[i], pollfds[i].fd, users,cmdBuf, 32) == -1)
printf("Connection closed\n");
else if(readCmd(&pollfds[i], pollfds[i].fd, users ,cmdBuf, 32) == -2)
printf("Error with recv");
}
}
readCmd(the command that reads from client):
int readCmd(struct pollfd * pollInfo, int sockfd, struct user *users,char* buf, int bufSize){
int num = recv(sockfd , buf, bufSize, 0);
if( num == -1)
return -2;
else if (num == 0 || (num < 0 && errno == ECONNRESET)){
// printf("Nothing to read\n");
close(sockfd);
return -1;
}
else{
printf("recieved %d bytes\n", num);
buf[num] = '\0';
char tokenList[5][30];
char* context = NULL;
char* token = strtok_r(buf, " ", &context);
// Parse command and arguments
int ite = 0;
while (token != NULL) {
strcpy(tokenList[ite], token);
ite++;
token = strtok_r(NULL, " ", &context);
}
if(strcmp(tokenList[0], "REGISTER") == 0){
registerAcc(tokenList[1], tokenList[2]);
}
else if (strcmp(tokenList[0], "LOGIN") == 0){
login(tokenList[1], tokenList[2], users);
}
}
return 0;
}

while loop for a game in C?

I have a word guessing game which I needs to repeat until the user types Q:. Generally, the answer is in a format A: answer. The game's using sockets!
Instead of while(1), I tried using while(buffer[0]!='Q') but that does not seem to work.
How do I keep making the client play the game?
Additionally, I also need to tell the user how many games he passed correctly?
while (1)
{
FD_ZERO(&readfds);
FD_SET(server_fd, &readfds);
int max_fd = server_fd;
for (int i = 0; i < NUMCLIENT; i++)
{
file_descriptor = client_sockets[i];
if (file_descriptor > 0)
{
FD_SET(file_descriptor, &readfds);
}
if (file_descriptor > max_fd)
{
max_fd = file_descriptor;
}
}
int return_value = select(max_fd + 1, &readfds, NULL, NULL, NULL);
if (return_value == -1)
{
printf("Select Error\n");
}
if (FD_ISSET(server_fd, &readfds))
{
if ((new_socket = accept(server_fd, (struct sockaddr *) &address,
(socklen_t*) &addrlen)) < 0)
{
perror("accept");
}
send(new_socket, greetings[0], strlen(greetings[0]), 0);
send(new_socket, greetings[1], strlen(greetings[1]), 0);
for (int i = 0; i < NUMCLIENT; i++)
{
if (client_sockets[i] == 0)
{
my_fortune(i);
client_sockets[i] = new_socket;
send(new_socket, client_challenges->question, strlen(client_challenges->question), 0);
break;
}
}
}
for (int i = 0; i < NUMCLIENT; i++)
{
file_descriptor = client_sockets[i];
if (file_descriptor == 0)
{
continue;
}
if (FD_ISSET(file_descriptor, &readfds))
{
memset(buffer, 0, 1024);
valread = read(file_descriptor, buffer, 1024);
if (valread == 0)
{
close(file_descriptor);
client_sockets[i] = 0;
continue;
}
printf("%s\n", buffer);
if (buffer[0] == 'A')
{
if (strlen(client_challenges->answer) == (strlen(buffer) - 4))
{
char store[100];
for (int i = 1; i <= strlen(client_challenges->answer); i++)
{
store[i - 1] = buffer[2 + i];
}
store[strcspn(store, "\r\n")] = 0;
if (strcmp(store, client_challenges->answer) == 0)
{
send(file_descriptor, correct, strlen(correct), 0);
//printf("O: Congratulation - challenge passed!\n");
}
else
{
send(file_descriptor, wrong, strlen(wrong), 0);
send(file_descriptor, client_challenges->answer, strlen(client_challenges->answer), 0);
}
//printf("Wrong guess - expected: %s",client_challenges->answer);}
}
else
{
send(file_descriptor, wrong, strlen(wrong), 0);
send(file_descriptor, client_challenges->answer, strlen(client_challenges->answer), 0);
}
//{printf("Wrong guess - expected: %s",client_challenges->answer);}
}
else if (buffer[0] == 'Q')
{
send(file_descriptor, ending, strlen(ending), 0);
exit(1);
}
else
{
send(file_descriptor, error, strlen(error), 0);
exit(1);
}
}
}
}
If there will only be 1 client, you can simply do
// Actual function to start the game
int play() {
int run = 1;
while (run) {
// run the game
// if game over,
run = 0;
}
return 0; // indicate the game ends gracefully
}
int main(int argc, char** argv) {
int run = 1;
int playAgain = 0;
while (run) {
if (play()) {
// Error: the game ends ungracefully
}
// Prompt for play again
if (!playAgain) {
run = 0;
}
}
// Bye
}
The reason is that the variable run is used to control the game flow. If the user quits or something went wrong, you can set run to 0 and the game will stop running.
If there are going to be multiple clients, you might want to have a look at pthread. Every time you receive a new connection, you can create a new thread with pthread_create and set the play function as start_routine and the fd as the argument. For example, you can try
int MAX_CLIENT = 5;
struct pthread_args {
int fd;
};
void* play(void* arg) {
struct pthread_args* args = (struct pthread_args*)arg;
int fd = args->fd;
// Start the game
}
int main(int argc, char** argv) {
pthread_t pth[MAX_CLIENT];
struct pthread_args pth_args;
int new_fd;
int i = 0;
while(1) { // The server continuously receive connections
// Accept connections
new_fd = accept(/*...*/)
if (new_fd < 0) {
// Error: accepting new connection
}
pth_args.fd = new_fd;
int r = pthread_create(&pth[i], NULL, play, &pth_args);
if (!r) {
// Error: creating thread
}
++i;
}
}
PS: You may want to have a look at pthread_detach as well.
Instead of while(1), I tried using while(buffer[0]!='Q') but that does not seem to work.
The reason while(buffer[0] == 'Q') doesn't work is because by the time the while check for the condition, the buffer (assuming it was declared outside of the while loop) might not be the same buffer anymore because you are looping over all clients and save the buffers from clients to the same buffer variable. So if there are 2 clients and the first client says 'Q' and the second client says 'A', the while sees buffer[0] as 'A' instead of 'Q' and hence continuing the game.
Also, I don't think exit(1) in else if (buffer[0] == 'Q') is a good idea. It kills the server and all clients will be forced to quit the game. Just remove the particular client from the client_sockets array.
:) Hope it helps

Strtok() returning NULL randomly

I am trying to create a client that communicate with a server by sending 2 types of messages:
The word QUIT that communicate to the server to close the connection.
An operation with the following syntax: operator first_operand second_operand. For example: + 3 3, - 5 6 etc. (the operands must be positive integers, and there must be only 2 operands).
If the server receive an operation, it executes it and returns the result to the client. The problem is that the first operation I send returns the right result, while the following ones work randomly (sometimes they return the right result, other times the function strtok() doesn't get the second operand and returns NULL...).
This is code of the client that process the message written by the user in the prompt and that scan the message to check if the operation is written with the correct syntax (WARNING: the code is written in an extremely unprofessional and unclean way).
The code part that creates the problem is inside the while(1).
#define MAXLENGTH 256
int main (int argc, char *argv[]) {
int simpleSocket = 0;
int simplePort = 0;
int returnStatus = 0;
char first[10], second[10];
char* operator;
char buffer[MAXLENGTH] = "";
char message[50];
char terminationCommand[] = "QUIT\n";
char space[2] = " ";
struct sockaddr_in simpleServer;
if (3 != argc) {
fprintf(stderr, "Usage: %s <server> <port>\n", argv[0]);
exit(1);
}
/* create a streaming socket */
simpleSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (simpleSocket == -1) {
fprintf(stderr, "Could not create a socket!\n");
exit(1);
} else {
fprintf(stderr, "Socket created!\n");
}
/* retrieve the port number for connecting */
simplePort = atoi(argv[2]);
/* setup the address structure */
/* use the IP address sent as an argument for the server address */
//bzero(&simpleServer, sizeof(simpleServer));
memset(&simpleServer, '\0', sizeof(simpleServer));
simpleServer.sin_family = AF_INET;
//inet_addr(argv[2], &simpleServer.sin_addr.s_addr);
simpleServer.sin_addr.s_addr=inet_addr(argv[1]);
simpleServer.sin_port = htons(simplePort);
/* connect to the address and port with our socket */
returnStatus = connect(simpleSocket, (struct sockaddr *)&simpleServer, sizeof(simpleServer));
if (returnStatus == 0) {
fprintf(stderr, "Connect successful!\n\n");
} else {
fprintf(stderr, "Could not connect to address!\n");
close(simpleSocket);
exit(1);
}
/* get the message from the server */
returnStatus = read(simpleSocket, buffer, sizeof(buffer));
if (returnStatus > 0) {
printf("%s\n", &buffer[3]);
} else {
fprintf(stderr, "Return Status = %d \n", returnStatus);
}
memset(&buffer, '\0', sizeof(buffer));
printf("You can execute 2 commands:\n");
printf("1. Operations ( +, -, *, /, % ) with the following syntax: operator + first operand + second operand.\n");
printf("Example: + 5 2 \n");
printf("2. Termination of the connection with the following syntax: QUIT + press Enter.\n");
while(1) {
printf("\nEnter a command:\n");
fgets(message, 1000, stdin);
// the if with the termination command works fine
if (strcmp(message, terminationCommand) == 0) {
if (send(simpleSocket, message, strlen(message), 0) < 0) {
printf("Send failed.");
return 1;
}
returnStatus = read(simpleSocket, buffer, sizeof(buffer));
if (returnStatus > 0) {
printf("%s\n", &buffer[4]);
} else {
fprintf(stderr, "Return Status = %d \n", returnStatus);
}
close(simpleSocket);
exit(1);
}
operator = strtok(message, space);
if (strcmp(operator, "+") == 0 || strcmp(operator, "-") == 0 || strcmp(operator, "/") == 0 || strcmp(operator, "%") == 0 || strcmp(operator, "*") == 0) {
char *first_operand = strtok(NULL, space);
if (first_operand != NULL) {
if (strcmp(first_operand, "ANS") == 0)
strcpy(first, "ANS");
else
strcpy(first, first_operand);
printf("%s\n", operator);
printf("%s\n", first);
char *second_operand = strtok(NULL, space);
printf("%s\n", second_operand);
if (second_operand != NULL && strtok(NULL, space) == NULL && (atoi(first) > 0 || strcmp(first, "ANS") == 0)) {
if (strcmp(second_operand, "ANS\n") == 0)
strcpy(second, "ANS");
else {
strcpy(second, second_operand);
}
if (atoi(second) > 0 || strcmp(second, "ANS") == 0) {
printf("OK\n");
char operation[] = "";
strcat(operation, operator);
strcat(operation, " ");
strcat(operation, first);
strcat(operation, " ");
strcat(operation, second);
if (send(simpleSocket, operation, strlen(operation), 0) < 0) {
printf("Send failed.");
return 1;
}
returnStatus = read(simpleSocket, buffer, sizeof(buffer));
if (returnStatus > 0) {
printf("%s\n", buffer);
} else {
fprintf(stderr, "Return Status = %d \n", returnStatus);
}
}
}
}
}
// after everything I reset the buffers I use to memorize the message and the elements of the message
memset(&buffer, '\0', sizeof(buffer));
memset(&first, '\0', sizeof(first));
memset(&second, '\0', sizeof(second));
memset(&message, '\0', sizeof(message));
memset(operator, '\0', sizeof(operator));
}
}
Can someone tell me why the second strtok() acts weird 90% of the times? What am I doing wrong?
There are multiple issues in you program:
You send newline terminated messages and you assume on the other end the read will return exactly the bytes sent by the other party, which is an incorrect assumption for the TCP/IP communications, only the order of bytes received is guaranteed, but the messages can be split on the way and received in chunks different from the sending sequence. You should instead read the socket into a buffer and only handle it once you receive a newline.
In your case, there is another problem which is more pressing: the buffer into which you read the data is not null terminated, so you should not pass it to standard C functions such as strtok().

Unable to receive data with libusb

I want to send and receive data from device to pc and vice versa. I am sending the string, but not able to receive it fully. Example: Sent string is Hello, and the output is:
Received:H
Error in read! e = -4 and received = 5
#include <string.h>
#include<stdio.h>
#include <stdlib.h>
#include <libusb-1.0/libusb.h>
#define BULK_EP_OUT 0x01
#define BULK_EP_IN 0x81
/*find these values using lsusb -v*/
uint16_t VENDOR = 0x0483;
uint16_t PRODUCT = 0x5740;
int main(void)
{
int ret = 1; //int type result
struct libusb_device **usb_dev;
struct libusb_device_descriptor desc;
struct libusb_device_handle *handle = NULL;
struct device_handle_expected;
//struct libusb_device_handle device_expected_handle = NULL;
struct libusb_device *dev, *dev_expected;
char *my_string, *my_string1;
int e = 0, config;
char found = 0;
int transferred = 0;
int received = 0;
int length = 0;
int i=0;
int count;
/*struct libusb_device *dev;
struct libusb_device **devs;
struct dev_expected;*/
// Initialize libusb
ret = libusb_init(NULL);
if(ret < 0)
{
printf("\nFailed to initialise libusb\n");
return 1;
}
else
printf("\nInit successful!\n");
// Get a list of USB devices
count = libusb_get_device_list(NULL, &usb_dev);
if (count < 0)
{
printf("\nThere are no USB devices on the bus\n");
return -1;
}
printf("\nToally we have %d devices\n", count);
while ((dev = usb_dev[i++]) != NULL)
{
ret = libusb_get_device_descriptor(dev, &desc);
if (ret < 0)
{
printf("Failed to get device descriptor\n");
libusb_free_device_list(dev, 1);
break;
}
e = libusb_open(dev, &handle);
if (e < 0)
{
printf("Error opening device\n");
libusb_free_device_list(dev, 1);
libusb_close(handle);
break;
}
if(desc.idVendor == 0x0483 && desc.idProduct == 0x5740)
{
found = 1;
break;
}
}//end of while
if(found == 0)
{
printf("\nDevice NOT found\n");
libusb_free_device_list(usb_dev, 1);
libusb_close(handle);
return 1;
}
else
{
printf("\nDevice found");
// dev_expected = dev;
//device_handle_expected = handle;
}
e = libusb_get_configuration(handle, &config);
if(e!=0)
{
printf("\n***Error in libusb_get_configuration\n");
libusb_free_device_list(usb_dev, 1);
libusb_close(handle);
return -1;
}
printf("\nConfigured value: %d", config);
if(config != 1)
{
libusb_set_configuration(handle, 1);
if(e!=0)
{
printf("Error in libusb_set_configuration\n");
libusb_free_device_list(usb_dev, 1);
libusb_close(handle);
return -1;
}
else
printf("\nDevice is in configured state!");
}
if(libusb_kernel_driver_active(handle, 0) == 1)
{
printf("\nKernel Driver Active");
if(libusb_detach_kernel_driver(handle, 0) == 0)
printf("\nKernel Driver Detached!");
else
{
printf("\nCouldn't detach kernel driver!\n");
libusb_free_device_list(usb_dev, 1);
libusb_close(handle);
return -1;
}
}
e = libusb_claim_interface(handle, 0);
if(e < 0)
{
printf("\nCannot Claim Interface");
libusb_free_device_list(usb_dev, 1);
libusb_close(handle);
return -1;
}
else
printf("\nClaimed Interface\n");
int nbytes = 64;
my_string = (char *) malloc(nbytes + 1);
my_string1 = (char *) malloc(nbytes + 1);
memset(my_string, '\0', 64);//The C library function void (an unsigned char) to the first n characters of the string pointed to, by the argument str.
memset(my_string1, '\0', 64);
strcpy(my_string, "Hello");
length = strlen(my_string);
printf("\nTo be sent: %s", my_string);
e = libusb_bulk_transfer(handle, BULK_EP_OUT, my_string, length, &transferred, 0);
if(e == 0 && transferred == length)
{
printf("\nWrite successful!");
printf("\nSent %d bytes with string: %s\n", transferred, my_string);
}
else
printf("\nError in write! e = %d and transferred = %d\n", e, transferred);
// sleep(3);
i = 0;
for(i = 0; i <= length; i++)
{
e = libusb_bulk_transfer(handle, BULK_EP_IN, my_string1,length, &received, 0); //64: Max Packet Length
if(e == 0 && received == length)
{
printf("\nReceived:");
printf("%c", my_string1[i]);
sleep(5);
}
else
{
printf("\nError in read! e = %d and received = %d bytes\n", e, received);
return -1;
}
}
libusb_release_interface(handle, 0);
libusb_free_device_list(usb_dev, 1);
libusb_close(handle);
libusb_exit(NULL);
printf("\n");
return 0;
}
Pretty certain the bulk in transfer will transfer the entire buffer at once(up to 64--or 512 if you're doing high speed--bytes), not a byte at a time.
You're iterating over the size of the expected buffer and doing a bulk in for each byte, and only printing out the first byte.
Get rid of the for loop on the read and change your printf() to be printf("%s\n",my_string1);

Receiving a malloc error when running a simple client program

I am trying to test a client program to make sure that it correctly sends and receives messages from a server. When I run the program I get this weird error from malloc. Any help would be great. I've been looking at this code for way too long. Thanks in advance.
Here is the error:
// The first test runs okay
TEST 1 :
Connected to server
-> Socket open success
-> Request sent success
-> Response received success
Testing print:
Response received: <replyLoadAvg>0.228027:0.250000:0.280273</replyLoadAvg>
LoadAvg for 1min :: 0.228027
LoadAvg for 5min :: 0.250000
LoadAvg for 15min :: 0.280273
Real response -> <replyLoadAvg>0.228027:0.250000:0.280273</replyLoadAvg>
// Then I get this error for some reason
clientc(17781) malloc: ********* error for object 0x7fd048404318: incorrect checksum for
freed object - object was probably modified after being freed.
********* set a breakpoint in malloc_error_break to debug
Abort trap: 6
here is the client code:
// prototype
char* verifyString(char*);
void printLoadAvg(char*);
int receiveResponse(int, char **);
int main(int argc, char *argv[])
{
int sockfd;
char *name;
char *port;
struct sockaddr_in * dest;
if(argc != 3)
{
printf("Not enough arguments -- Exiting program\n");
return 0;
}
name = argv[1];
port = argv[2];
char * received;
char send[256];
char testMessages[5][256] = {"<loadavg/>", "<echo>Hello World!</echo>", "<echo> </echo>", "", "<echo>Bye Bye World...<echo>"};
char expectedResponses[5][256] = {"", "<reply>Hello World!</reply>", "<reply></reply>","<error>unknown format</error>", "<error>unknown format</error>"};
int i;
srand(time(NULL));
for(i = 0; i < 5; i++)
{
printf("\nTEST %i", i+1);
printf(((rand() % 2) ? ":\n" : " :\n"));
sprintf(send, "%s", testMessages[i]);
sockfd = createSocket(name, atoi(port), &dest);
if(sockfd < 0){
printf(" xx Open socket failed\n");
}
else{
printf(" -> Socket open success\n");
if(sendRequest(sockfd, send, dest) < 0){
printf(" xx Send failed\n");
}
else{
printf(" -> Request sent success\n");
if(receiveResponse(sockfd, &received) < 0){
printf(" xx Receive failed\n");
}
else{
printf(" -> Response received success\n");
if(i!=0 && strcmp(received, expectedResponses[i]) != 0){
printf("Incorrect message\n");
printf("Expected: %s\n", expectedResponses[i]);
printf("Received: %s\n", received);
}
else if(i!=0){
printf("Test %i. passed successfully!\n", i+1);
}
else{
printf("Testing print:\n");
printResponse(received);
fprintf(stdout, "Real response -> %s\n", received);
}
}
}
}
free(received);
free(dest);
if(closeSocket(sockfd)==0){
printf(" -> Socket closed success\n");
}
else{
printf(" XX Close failed\n");
}
}
return 0;
}
int createSocket( char* hostname, int port, struct sockaddr_in** dest)
{
// fill in the socket address struct
(*dest) = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
struct hostent *hostptr;
hostptr = gethostbyname(hostname);
int socketfd;
memset((void *) (*dest), 0, (size_t)sizeof(struct sockaddr_in));
(*dest)->sin_family = (short)(AF_INET);
memcpy((void*)& (*dest)->sin_addr, (void *) hostptr->h_addr, hostptr->h_length);
(*dest)->sin_port = htons((u_short)port);
// now get the file descriptor for the socket
if((socketfd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
return -1;
}
// connect to the server at the location displayed by TCPserver.c
if(connect(socketfd, (struct sockaddr*)(*dest), sizeof(struct sockaddr)) < 0) {
perror("Error: call to connect()\n");
return -1;
}
printf("Connected to server\n");
return socketfd;
}
int sendRequest(int sock, char* request, struct sockaddr_in* dest)
{
// send a request through the socket to the server.
if(write(sock, request, BUFFERSIZE) < 0)
{
return -1;
}
return 0;
}
int receiveResponse(int sock, char ** response)
{
// dynamically allocate memory to be used in this function
(*response) = malloc(sizeof(char));
// wait for a response from the server
if(read(sock, (*response), BUFFERSIZE) < 0)
{
return -1;
}
return 0;
}
int closeSocket(int sock)
{
int error = 0;
if(close(sock))
{
perror("Error: Failed to close socket\n");
error = -1;
}
return error;
}
void printResponse(char* response)
{
char* buffer = "<replyloadavg>";
int i, isLoadAvg = 0;
// verify the string is in the correct format by calling the verifty string function
// then print the string to the screen.
printf("Response received: %s\n", verifyString(response));
for(i = 0; i < 14; i++)
{
if(response[i] == buffer[i])
isLoadAvg = 0;
else
{
isLoadAvg = 1;
i = 15;
}
}
if (isLoadAvg)
{
printLoadAvg(response);
}
}
char* verifyString(char* string)
{
int i, count = 0;
// step through the array until you come to the last '>' (the end of the string)
// then insert the NULL terminator at the end of the string.
for(i = 0; i < BUFFERSIZE; i++)
{
if(string[i] == '>')
count++;
if(count == 2)
{
string[i + 1] = '\0';
i = BUFFERSIZE;
}
}
return string;
}
void printLoadAvg(char* string)
{
int i = 0, j;
// these three arrays hold the newly formated strings, the ones that are easier to read.
char s1[BUFFERSIZE], s2[BUFFERSIZE], s3[BUFFERSIZE];
// step through the string until you reach the end of the string
while(string[i] != '>')
{
i++;
}
i++;
// now insert a colon and then save the contents of the string to the appropriate s array.
for(j = 0; string[i] != ':'; j++, i++)
{
s1[j] = string[i];
}
// be sure to set the null terminator at the end.
s1[j] = '\0';
i++;
for(j = 0; string[i] != ':'; j++, i++)
{
s2[j] = string[i];
}
// be sure to set the null terminator at the end.
s2[j] = '\0';
i++;
// now move to the beginning of the end of the string array
for(j = 0; string[i] != '<'; j++, i++)
{
s3[j] = string[i];
}
// now insert one more null terminator for the final s array.
s3[j] = '\0';
// now print out the newly fomrated strings.
printf("\nLoadAvg for 1min :: %s\n", s1);
printf("LoadAvg for 5min :: %s\n", s2);
printf("LoadAvg for 15min :: %s\n", s3);
}
(*response) = malloc(sizeof(char));
// wait for a response from the server
if(read(sock, (*response), BUFFERSIZE) < 0)
What size is BUFFERSIZE. Is it bigger than 1? If so, you will overflow your buffer...

Resources