0

The task was to write a program using INET domain, so I did. But there is one small thing to do that I don't know how to perform. the first non-blank character of the input line is 'u', the server will send to the client the output of the 'uptime' command executed on the server's host.

Program is running under Linux(Ubuntu).

Which could be like:

    if (strcmp(send_data , "u") == 0 || strcmp(send_data , "U") == 0)
    {
        send(sock, uptimevar, strlen(uptimevar), 0);               
    }

But how to get uptime of any command in C?

Server Code:

/* tcpserver.c */

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/sysinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

int main()
{
int sock, connected, bytes_recieved , true = 1;  
char send_data [1024] , recv_data[1024];       

struct sockaddr_in server_addr,client_addr/*, sysinfo*/;    
int sin_size;

if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("Socket");
    exit(1);
}

if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&true,sizeof(int)) == -1) {
    perror("Setsockopt");
    exit(1);
}

server_addr.sin_family = AF_INET;         
server_addr.sin_port = htons(1237);     
server_addr.sin_addr.s_addr = INADDR_ANY; 
bzero(&(server_addr.sin_zero),8); 

if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr))
                                                               == -1) {
    perror("Unable to bind");
    exit(1);
}

if (listen(sock, 5) == -1) {
    perror("Listen");
    exit(1);
}

printf ("\nTCPServer Waiting for client on port 5000");
    fflush(stdout);
while(1)
{  

    sin_size = sizeof(struct sockaddr_in);

    connected = accept(sock, (struct sockaddr *)&client_addr,&sin_size);

    printf("\n I got a connection from (%s , %d)",
           inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));

    while (1)
    {
        printf("\n SEND (q or Q to quit) : ");
        fgets(send_data, sizeof(send_data), stdin);

        if (strcmp(send_data , "q") == 0 || strcmp(send_data , "Q") == 0)
        {
          send(connected, send_data,strlen(send_data), 0); 
          close(connected);
          break;
        }

        else 
        {
            send(connected, send_data,strlen(send_data), 0);  
            //printf("Uptime = %ld\n", connected.uptime);

            bytes_recieved = recv(connected,recv_data,1024,0);

            recv_data[bytes_recieved] = '\0';
        }
        if (strcmp(recv_data , "q") == 0 || strcmp(recv_data , "Q") == 0)
        {
          close(connected);
          break;
        }

        else {
            printf("\n RECIEVED DATA = %s " , recv_data);
            fflush(stdout);   
        }
    }
}       
close(sock);
return 0;
}

Client Code:

/* tcpclient.c */

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>


int main()
{

int sock, bytes_recieved;  
char send_data[1024],recv_data[1024];
struct hostent *host;
struct sockaddr_in server_addr;  

host = gethostbyname("127.0.0.1");

if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("Socket");
    exit(1);
}

server_addr.sin_family = AF_INET;     
server_addr.sin_port = htons(1237);   
server_addr.sin_addr = *((struct in_addr *)host->h_addr);
bzero(&(server_addr.sin_zero),8); 

if (connect(sock, (struct sockaddr *)&server_addr,
            sizeof(struct sockaddr)) == -1) 
{
    perror("Connect");
    exit(1);
}

while(1)
{
    bytes_recieved=recv(sock,recv_data,1024,0);
    recv_data[bytes_recieved] = '\0';

    if (strcmp(recv_data , "q") == 0 || strcmp(recv_data , "Q") == 0)
    {
        close(sock);
        break;
    }

    else 
    {
        printf("\nRecieved data = %s " , recv_data);
        printf("\nSEND (q or Q to quit) : ");
        fgets(send_data, sizeof(send_data), stdin);
    } 
    if (strcmp(send_data , "q") == 0 || strcmp(send_data , "Q") == 0)
    {
        send(sock, send_data, strlen(send_data), 0);   
        close(sock);            
        break;
    }
    else
    {
        send(sock,send_data, strlen(send_data), 0);           
    }
}   
return 0;
}

Modification:

/* tcpserver.c */

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/sysinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

int main()
{
int sock, connected, bytes_recieved , true = 1;  
char send_data [1024] , recv_data[1024];       
struct sockaddr_in server_addr,client_addr/*, sysinfo*/; 
struct sysinfo info;   
int sin_size;

if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("Socket");
    exit(1);
}

if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&true,sizeof(int)) == -1) {
    perror("Setsockopt");
    exit(1);
}

server_addr.sin_family = AF_INET;         
server_addr.sin_port = htons(1237);     
server_addr.sin_addr.s_addr = INADDR_ANY; 
bzero(&(server_addr.sin_zero),8); 

if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr))
                                                               == -1) {
    perror("Unable to bind");
    exit(1);
}

if (listen(sock, 5) == -1) {
    perror("Listen");
    exit(1);
}

printf ("\nTCPServer Waiting for client on port 1237");
    fflush(stdout);
while(1)
{  

    sin_size = sizeof(struct sockaddr_in);

    connected = accept(sock, (struct sockaddr *)&client_addr,&sin_size);

    //sysinfo(&connected);
    printf("\n I got a connection from (%s , %d)",
           inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
    send(connected, "Hello this is a simple server", 100, 1);

    while (1)
    {
        printf("\n SEND (q or Q to quit) : ");
        fgets(send_data, sizeof(send_data), stdin);

        bytes_recieved = recv(connected,recv_data,1024,0);
        recv_data[bytes_recieved] = '\0';

        if (strcmp(recv_data , "u") == 0 || strcmp(recv_data , "U") == 0)
            {
            if (sysinfo(&info) == 0) {
               snprintf(send_data, sizeof send_data, "Uptime: %ld seconds\n", info.uptime);
            } else {
               snprintf(send_data, sizeof send_data, "Error getting uptime: %s\n", strerror(errno));
            }
            send(connected, send_data,strlen(send_data), 0);  
        }

    }       
    close(sock);
    return 0;
}
}
pnuts
  • 58,317
  • 11
  • 87
  • 139
RegarBoy
  • 3,228
  • 1
  • 23
  • 44
  • This would be a lot easier if you could just call a function to get the current uptime, instead of executing the uptime command. If you would rather do that, then tell us what operating system you're running on, since the API for getting the uptime is system specific. – nos Nov 10 '15 at 14:09
  • 1
    "*how to get uptime of any command*" please elaborate on what you actually are after? And BTW, you are aware there is an IXish command *called* `uptime`, are you? – alk Nov 10 '15 at 16:59
  • Also I'd say get your networking code proper. For example **always** check the outcome of the `recv()` function as it is not expected to necessarily return as many bytes as it was told to. Moreover error checking is *mandatory* here for `send()` as well. All in all just read the docs carefully. – alk Nov 10 '15 at 17:10
  • And: There is this saying that networking code which calls `strlen()` would never work! ;-) – alk Nov 10 '15 at 17:11

1 Answers1

1

You shouldn't execute the uptime command, instead call the API from your code to obtain the uptime, on linux this is done with the sysinfo() function.

#include <sys/sysinfo.h>
...

struct sysinfo info

if (sysinfo(&info) == 0) {
   snprintf(send_data, sizeof send_data, "Uptime: %ld seconds\n", info.uptime);
} else {
   snprintf(send_data, sizeof send_data, "Error getting uptime: %s\n", strerror(errno));
}

send(sock, send_data, strlen(send_data), 0);   
nos
  • 223,662
  • 58
  • 417
  • 506
  • probably either order or declaration of my statements are wrong which are: if (strcmp(recv_data , "u") == 0 || strcmp(recv_data , "U") == 0) { send(sock, uptimevar, strlen(uptimevar), 0); } How can I write a statement if recived data is u ? – RegarBoy Nov 10 '15 at 14:48
  • @developer I don't know what that code in your comment is supposed to do, as there is no context, you didn't show where you added the code I showed here (which would be best used inside that `if` statement - also you didn't say anything about what's not working – nos Nov 10 '15 at 14:51
  • You can find modified code with your answer in my question. – RegarBoy Nov 10 '15 at 14:59
  • whilst you're technically completely correct, the OP has specifically been told to send the output of the `uptime` command. That would involve such things as `fork`, `pipe` etc. – Alnitak Nov 10 '15 at 14:59
  • @Altinak That is why I asked in comments if the OP would rather go down the route of calling an API function for that, and I interpreted the response as an implicit yes. – nos Nov 10 '15 at 15:01
  • nos Please find 'Midification' in my question, there I have applied changes in second loop – RegarBoy Nov 10 '15 at 15:02
  • 1
    @developer I'm sorry but I don't think anyone can help you if you don't tell us what the problem is. – nos Nov 10 '15 at 15:06
  • If you see my code in the second `while` loop of server file I did follow your way with if statement. But when I send 'u' from client, server is not sending uptime to the client – RegarBoy Nov 10 '15 at 15:11
  • @developer Ok, please update your post with such important information. Though you might need to debug what you're actually reading. Perhaps you're also sending a new line, so your server receives "u\n". You could perhaps just compare the first character, `if (send_data[0] =='u')` instead of using strcmp. – nos Nov 10 '15 at 17:28